Class: TurboRex::MSRPC::RPCFinder::ImageFinder
Defined Under Namespace
Classes: AutoFindConf, InterfaceModel
Constant Summary
TurboRex::MSRPC::RPCBase::DCE_TransferSyntax, TurboRex::MSRPC::RPCBase::GUID, TurboRex::MSRPC::RPCBase::MIDL_SERVER_INFO, TurboRex::MSRPC::RPCBase::MIDL_SERVER_INFO32, TurboRex::MSRPC::RPCBase::MIDL_SERVER_INFO64, TurboRex::MSRPC::RPCBase::MIDL_STUBLESS_PROXY_INFO, TurboRex::MSRPC::RPCBase::MIDL_STUBLESS_PROXY_INFO32, TurboRex::MSRPC::RPCBase::MIDL_STUBLESS_PROXY_INFO64, TurboRex::MSRPC::RPCBase::MIDL_STUB_DESC, TurboRex::MSRPC::RPCBase::MIDL_STUB_DESC32, TurboRex::MSRPC::RPCBase::MIDL_STUB_DESC64, TurboRex::MSRPC::RPCBase::MIDL_SYNTAX_INFO, TurboRex::MSRPC::RPCBase::MIDL_SYNTAX_INFO32, TurboRex::MSRPC::RPCBase::MIDL_SYNTAX_INFO64, TurboRex::MSRPC::RPCBase::NDR64_TransferSyntax, TurboRex::MSRPC::RPCBase::RPC_DISPATCH_TABLE_T, TurboRex::MSRPC::RPCBase::RPC_DISPATCH_TABLE_T32, TurboRex::MSRPC::RPCBase::RPC_DISPATCH_TABLE_T64, TurboRex::MSRPC::RPCBase::RPC_IF_ID, TurboRex::MSRPC::RPCBase::RPC_PROTSEQ_ENDPOINT, TurboRex::MSRPC::RPCBase::RPC_PROTSEQ_ENDPOINT32, TurboRex::MSRPC::RPCBase::RPC_PROTSEQ_ENDPOINT64, TurboRex::MSRPC::RPCBase::RPC_SERVER_INTERFACE, TurboRex::MSRPC::RPCBase::RPC_SERVER_INTERFACE32, TurboRex::MSRPC::RPCBase::RPC_SERVER_INTERFACE64, TurboRex::MSRPC::RPCBase::RPC_SYNTAX_IDENTIFIER, TurboRex::MSRPC::RPCBase::RPC_SYNTAX_IDENTIFIER64, TurboRex::MSRPC::RPCBase::RPC_Struct_Mgr32, TurboRex::MSRPC::RPCBase::RPC_Struct_Mgr64, TurboRex::MSRPC::RPCBase::RPC_VERSION
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#auto_find(&block) ⇒ Object
-
#close ⇒ Object
-
#decompile_func(addr) ⇒ Object
-
#disassemble(addr, dasm = nil) ⇒ Object
-
#disassemble_executable_sections(dasm = nil) ⇒ Object
-
#disassemble_fast(addr, dasm = nil) ⇒ Object
-
#disassemble_fast_deep(addr, dasm = nil) ⇒ Object
-
#draw_ifs_xrefs ⇒ Object
Xrefs in the same binary file.
-
#find_client_disp_functions(va, dasm, expr, *funcs) ⇒ Object
-
#find_client_routines(client_if, client_if_addr, dasm = nil) ⇒ Object
-
#find_rpc_server_interface(opts = {}) ⇒ Object
-
#get_disp_functions(rpc_dispatch_table) ⇒ Object
-
#get_dispatch_table(rpc_server_if) ⇒ Object
-
#get_endpoint_info(rpc_server_if) ⇒ Object
-
#get_midl_server_info(rpc_server_if) ⇒ Object
-
#get_midl_stub_desc(midl_server_info) ⇒ Object
-
#get_midl_syntax_info(midl_server_info) ⇒ Object
-
#get_offset_table(rpc_server_if) ⇒ Object
-
#get_offset_table2(disptbl, midl_server_info) ⇒ Object
-
#get_routines_from_server_interface(rpc_server_interface) ⇒ Object
-
#get_rpc_server_routines(midl_server_info, count) ⇒ Object
-
#get_stubless_pinfo_from_client_if(rpc_client_if) ⇒ Object
-
#initialize(pe, _opts = {}) ⇒ ImageFinder
constructor
A new instance of ImageFinder.
-
#make_midl_server_info(pe) ⇒ Object
-
#make_midl_stub_desc(pe) ⇒ Object
-
#make_midl_stubless_proxy_info(pe) ⇒ Object
-
#make_midl_syntax_info(pe) ⇒ Object
-
#make_rpc_dispatch_table_t(pe) ⇒ Object
-
#make_rpc_protseq_endpoint(pe) ⇒ Object
-
#make_rpc_server_interface(pe) ⇒ Object
-
#new_dasm ⇒ Object
-
#open_file(filename) ⇒ Object
-
#reconstruct_disp_functions(pe, rpc_dispatch_table) ⇒ Object
-
#reconstruct_disptbl_for_midl_server_info(pe, midl_server_info, count) ⇒ Object
-
#reconstruct_disptbl_for_server_interface(pe, rpc_server_interface) ⇒ Object
-
#reconstruct_disptbl_from_addr(pe, addr) ⇒ Object
-
#reconstruct_endpoint_info(pe, server_if) ⇒ Object
-
#reconstruct_midl_server_info(pe, rpc_server_interface) ⇒ Object
-
#reconstruct_midl_stub_desc(pe, midl_server_info) ⇒ Object
-
#reconstruct_midl_syntax_info(pe, midl_server_info) ⇒ Object
-
#reconstruct_offset_table(pe, server_if) ⇒ Object
-
#reconstruct_offset_table2(pe, disptbl, midl_server_info) ⇒ Object
-
#reconstruct_struct_from_pe(pe, rva, cstruct) ⇒ Object
-
#reconstruct_stubless_pinfo(pe, client_if) ⇒ Object
-
#scan_xrefs_immediate(addr, dasm = nil) ⇒ Object
-
#validate_midl_stub_desc(pe, struct) ⇒ Object
-
#validate_rpc_server_interface(pe, rpc_server_interface) ⇒ Object
-
#validate_server_interface_from_pe(pe, address) ⇒ Object
-
#validate_stubless_proxy_info(pe, stubless_proxy_info, strict_check = true) ⇒ Object
The “strict_check” option will use the algorithm of NdrClientCall3.
-
#validate_transfer_syntax(transfer_syntax) ⇒ Object
#bt_security_callback
#_disassemble_executable_sections, #add_dasm_all_method, #addrtolabel, #backtrace, #solve_cppobj_call, #solve_guard_icall
data_section?, #draw_xrefs_dg, #has_path?, scan_all_sections, scan_section
from_guid_str, make_transferSyntax
Methods included from CStruct
#define_structs
Constructor Details
#initialize(pe, _opts = {}) ⇒ ImageFinder
Returns a new instance of ImageFinder.
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 381
def initialize(pe, _opts = {})
open_file(pe)
@server_interfaces = []
@midl_server_infos = []
@midl_stub_descs = []
@midl_syntax_infos = []
@midl_stubless_proxy_infos = []
@server_routines = []
@dispatch_funcs = []
@client_interfaces = []
@dasm = new_dasm
@collection_proxy = _opts[:collection_proxy]
arch = @pe.ptr_32? ? 'x86' : 'x64'
@ndr_decompiler = TurboRex::MSRPC::Decompiler.new(arch: arch)
end
|
Instance Attribute Details
#client_interfaces ⇒ Object
Returns the value of attribute client_interfaces.
378
379
380
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 378
def client_interfaces
@client_interfaces
end
|
#client_routines ⇒ Object
Returns the value of attribute client_routines.
379
380
381
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 379
def client_routines
@client_routines
end
|
#dasm ⇒ Object
Returns the value of attribute dasm.
369
370
371
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 369
def dasm
@dasm
end
|
#dispatch_funcs ⇒ Object
Returns the value of attribute dispatch_funcs.
375
376
377
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 375
def dispatch_funcs
@dispatch_funcs
end
|
#midl_server_infos ⇒ Object
Returns the value of attribute midl_server_infos.
372
373
374
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 372
def midl_server_infos
@midl_server_infos
end
|
#midl_stubless_proxy_infos ⇒ Object
Returns the value of attribute midl_stubless_proxy_infos.
374
375
376
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 374
def midl_stubless_proxy_infos
@midl_stubless_proxy_infos
end
|
#midl_syntax_infos ⇒ Object
Returns the value of attribute midl_syntax_infos.
373
374
375
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 373
def midl_syntax_infos
@midl_syntax_infos
end
|
#ndr_decompiler ⇒ Object
Returns the value of attribute ndr_decompiler.
370
371
372
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 370
def ndr_decompiler
@ndr_decompiler
end
|
#pe ⇒ Object
Returns the value of attribute pe.
368
369
370
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 368
def pe
@pe
end
|
#server_interfaces ⇒ Object
Returns the value of attribute server_interfaces.
371
372
373
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 371
def server_interfaces
@server_interfaces
end
|
#server_routines ⇒ Object
Returns the value of attribute server_routines.
376
377
378
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 376
def server_routines
@server_routines
end
|
Class Method Details
.glob(path, suffixes = nil) ⇒ Object
403
404
405
406
407
408
409
410
411
412
413
414
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 403
def self.glob(path, suffixes = nil)
pattern = []
suffixes&.each { |suffix| pattern << File.join(path, '*') + suffix }
if block_given?
Dir.glob(pattern) do |filename|
yield(filename)
end
else
Dir.glob(pattern)
end
end
|
.glob_all(root) ⇒ Object
399
400
401
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 399
def self.glob_all(root)
Dir.glob(root + '/**/*')
end
|
Instance Method Details
#auto_find(&block) ⇒ Object
436
437
438
439
440
441
442
443
444
445
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 436
def auto_find(&block)
default = TurboRex::MSRPC::RPCFinder::ImageFinder::AutoFindConf.new
config = if block_given?
Docile.dsl_eval(default, &block).build
else
default.build
end
internal_auto_find(config)
end
|
#close ⇒ Object
427
428
429
430
431
432
433
434
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 427
def close
unless @pe.nil?
@pe.close
@pe = nil
end
true
end
|
#decompile_func(addr) ⇒ Object
997
998
999
1000
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 997
def decompile_func(addr)
dasm = disassemble_fast(addr)[0]
dasm.decompiler.decompile(addr) end
|
#disassemble(addr, dasm = nil) ⇒ Object
979
980
981
982
983
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 979
def disassemble(addr, dasm = nil)
dasm ||= (@dasm || new_dasm)
res = dasm.disassemble addr
[dasm, res]
end
|
#disassemble_executable_sections(dasm = nil) ⇒ Object
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 1002
def disassemble_executable_sections(dasm = nil)
exe_sections = @pe.executable_sections
unless exe_sections.empty?
dasm ||= (@dasm || new_dasm)
add_dasm_all_method(dasm)
exe_sections.each do |s|
dasm.dasm_all(@pe.rva_to_vma(s.base_rva), s.raw_size)
end
addrtolabel(dasm)
dasm
end
end
|
#disassemble_fast(addr, dasm = nil) ⇒ Object
991
992
993
994
995
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 991
def disassemble_fast(addr, dasm = nil)
dasm ||= (@dasm || new_dasm)
res = dasm.disassemble_fast(addr)
[dasm, res]
end
|
#disassemble_fast_deep(addr, dasm = nil) ⇒ Object
985
986
987
988
989
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 985
def disassemble_fast_deep(addr, dasm = nil)
dasm ||= (@dasm || new_dasm)
res = dasm.disassemble_fast_deep(addr)
[dasm, res]
end
|
#draw_ifs_xrefs ⇒ Object
Xrefs in the same binary file
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 956
def draw_ifs_xrefs
@server_interfaces.each do |si|
@client_interfaces.each do |ci|
calls = []
ci.routines.each do |cr|
unless (res = si.func_in_server_routines(cr.addr)).empty?
calls << { caller: res, called: cr }
end
end
next if calls.empty?
si.xrefs_from << [ci, calls]
ci.xrefs_to << [si, calls]
si.xrefs_from.uniq!
si.xrefs_to.uniq!
end
end
end
|
#find_client_disp_functions(va, dasm, expr, *funcs) ⇒ Object
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 587
def find_client_disp_functions(va, dasm, expr, *funcs)
disassemble_executable_sections(dasm)
dispatch_funcs = []
if expr.nil?
case dasm.cpu.size
when 64
expr = 'rcx'
when 32
expr = '[esp]'
end
end
funcs.each do |func|
callers = dasm.call_sites(Metasm::Expression[func])
callers.each do |addr|
found, log = backtrace(addr, dasm, expr)
next unless found.include?(va)
proc_num = nil
case func
when 'NdrClientCall' expr_procnum = '[esp+4]'
switch = :Oi
when 'NdrClientCall2' expr_procnum = dasm.cpu.size == 64 ? 'rdx' : '[esp+4]'
switch = :Oicf
when 'NdrClientCall3'
expr_procnum = 'rdx'
when 'NdrClientCall4' expr_procnum = dasm.cpu.size == 64 ? 'rdx' : '[esp+4]'
end
_found, _log = backtrace(addr, dasm, expr_procnum)
unless _found.empty?
if func == 'NdrClientCall3'
proc_num = _found.first
else
_dasm = dasm.dup
_dasm.c_parser = @ndr_decompiler.parser
, = @ndr_decompiler.(_dasm, _found[0])
proc_num = ..common.ProcNum
end
end
yield(addr, dasm) if block_given?
func_start = dasm.find_function_start(addr)
dispatch_funcs << {
dispatch_func: func_start,
backtrace: [func, va, log],
proc_num: proc_num
}
end
end
dispatch_funcs
end
|
#find_client_routines(client_if, client_if_addr, dasm = nil) ⇒ Object
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 648
def find_client_routines(client_if, client_if_addr, dasm = nil)
dasm = @dasm || (@dasm = new_dasm)
disp_funcs = []
if has_proxy_info?(client_if) if proxy_info = get_stubless_pinfo_from_client_if(client_if)
pi_obj = TurboRex::MSRPC::RPCBase::MIDL_STUBLESS_PROXY_INFO_Klass.new(proxy_info)
pinterpreter_info = client_if.InterpreterInfo_Value
@midl_stubless_proxy_infos << pi_obj
client_if.midl_switches << %w[all win64 amd64 ia64]
client_if.link_to pi_obj
disp_funcs = find_client_disp_functions(pinterpreter_info, dasm, nil, 'NdrClientCall3')
end
else
xrefs = scan_xrefs_immediate(client_if_addr, dasm)
xrefs.each do |xref|
midl_stub_desc = make_midl_stub_desc(@pe)
reconstruct_struct_from_pe(@pe, @pe.vma_to_rva(xref), midl_stub_desc)
next unless validate_midl_stub_desc(@pe, midl_stub_desc)
stub_desc_obj = MIDL_STUB_DESC_Klass.new(midl_stub_desc)
stub_desc_obj.link_to client_if
@midl_stub_descs << stub_desc_obj
disp_funcs = find_client_disp_functions(xref, dasm, nil, 'NdrClientCall', 'NdrClientCall2', 'NdrClientCall4')
next unless b = disp_funcs[0]&.fetch(:backtrace) { }
client_if.midl_switches << %w[Oi Oic] if b[0] == 'NdrClientCall'
if b[0] == 'NdrClientCall2'
client_if.midl_switches << %w[Oif Oicf]
end
end
end
disp_funcs.map do |m|
r = TurboRex::MSRPC::RPCBase::CLIENT_ROUTINE_Klass.new(m[:dispatch_func])
r.proc_num = m[:proc_num]
r
end.uniq(&:addr)
end
|
#find_rpc_server_interface(opts = {}) ⇒ Object
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 553
def find_rpc_server_interface(opts = {})
rpc_server_interface = make_rpc_server_interface(@pe)
regexp = Regexp.new [rpc_server_interface.slength].pack('V')
res = []
opts[:only_data_section] ||= true
if opts[:only_data_section]
@pe.data_sections.each do |s|
TurboRex::PEFile::Scanner.scan_section(s, regexp).each do |r|
rpc_server_interface = make_rpc_server_interface(@pe)
next unless reconstruct_struct_from_pe(@pe, r[0], rpc_server_interface) > 0
if validate_rpc_server_interface(@pe, rpc_server_interface)
yield(rpc_server_interface, r[0]) if block_given?
res << rpc_server_interface
end
end
end
else
addr_info = TurboRex::PEFile::Scanner.scan_all_sections(@pe, regexp)
unless addr_info.empty?
addr_info.each do |addr|
rpc_server_interface = make_rpc_server_interface(@pe)
if reconstruct_struct_from_pe(@pe, addr[0], rpc_server_interface) > 0
yield(rpc_server_interface, addr[0]) if block_given?
res << rpc_server_interface
end
end
end
end
res
end
|
#get_disp_functions(rpc_dispatch_table) ⇒ Object
535
536
537
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 535
def get_disp_functions(rpc_dispatch_table)
reconstruct_disp_functions(@pe, rpc_dispatch_table)
end
|
#get_dispatch_table(rpc_server_if) ⇒ Object
519
520
521
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 519
def get_dispatch_table(rpc_server_if)
reconstruct_disptbl_for_server_interface(@pe, rpc_server_if)
end
|
#get_endpoint_info(rpc_server_if) ⇒ Object
531
532
533
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 531
def get_endpoint_info(rpc_server_if)
reconstruct_endpoint_info(@pe, rpc_server_if)
end
|
#get_midl_server_info(rpc_server_if) ⇒ Object
503
504
505
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 503
def get_midl_server_info(rpc_server_if)
reconstruct_midl_server_info(@pe, rpc_server_if)
end
|
#get_midl_stub_desc(midl_server_info) ⇒ Object
507
508
509
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 507
def get_midl_stub_desc(midl_server_info)
reconstruct_midl_stub_desc(@pe, midl_server_info)
end
|
#get_midl_syntax_info(midl_server_info) ⇒ Object
515
516
517
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 515
def get_midl_syntax_info(midl_server_info)
reconstruct_midl_syntax_info(@pe, midl_server_info)
end
|
#get_offset_table(rpc_server_if) ⇒ Object
523
524
525
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 523
def get_offset_table(rpc_server_if)
reconstruct_offset_table(@pe, rpc_server_if)
end
|
#get_offset_table2(disptbl, midl_server_info) ⇒ Object
527
528
529
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 527
def get_offset_table2(disptbl, midl_server_info)
reconstruct_offset_table2(@pe, disptbl, midl_server_info)
end
|
#get_routines_from_server_interface(rpc_server_interface) ⇒ Object
543
544
545
546
547
548
549
550
551
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 543
def get_routines_from_server_interface(rpc_server_interface)
if has_interpreter_info?(rpc_server_interface)
disptbl = get_dispatch_table(rpc_server_interface)
midl_server_info = get_midl_server_info(rpc_server_interface)
count = disptbl['dispatchTableCount'].value
get_rpc_server_routines(midl_server_info, count) if count > 0
end
end
|
#get_rpc_server_routines(midl_server_info, count) ⇒ Object
539
540
541
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 539
def get_rpc_server_routines(midl_server_info, count)
reconstruct_disptbl_for_midl_server_info(@pe, midl_server_info, count)
end
|
#get_stubless_pinfo_from_client_if(rpc_client_if) ⇒ Object
511
512
513
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 511
def get_stubless_pinfo_from_client_if(rpc_client_if)
reconstruct_stubless_pinfo(@pe, rpc_client_if)
end
|
#make_midl_server_info(pe) ⇒ Object
#make_midl_stub_desc(pe) ⇒ Object
#make_midl_stubless_proxy_info(pe) ⇒ Object
#make_midl_syntax_info(pe) ⇒ Object
#make_rpc_dispatch_table_t(pe) ⇒ Object
#make_rpc_protseq_endpoint(pe) ⇒ Object
#make_rpc_server_interface(pe) ⇒ Object
#new_dasm ⇒ Object
930
931
932
933
934
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 930
def new_dasm
exe = Metasm::PE.decode_file @pe.image_path.to_s
exe.disassembler
end
|
#open_file(filename) ⇒ Object
416
417
418
419
420
421
422
423
424
425
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 416
def open_file(filename)
begin
@pe = TurboRex::PEFile::PE.new_from_file(filename)
@pe.image_path = Pathname.new(filename)
rescue FileHeaderError
return false
end
pe
end
|
#reconstruct_disp_functions(pe, rpc_dispatch_table) ⇒ Object
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 882
def reconstruct_disp_functions(pe, rpc_dispatch_table)
count = rpc_dispatch_table['dispatchTableCount'].value
pdispatch_table = pe.vma_to_rva(rpc_dispatch_table['dispatchTable'].value)
dispatch_funcs = []
if pe.ptr_32?
ptr_len = 4
format = 'V'
func_name = 'read_dword'
else
ptr_len = 8
format = 'Q<'
func_name = 'read_qword'
end
unless pdispatch_table == 0
count.times do |i|
code = "#{func_name}(pe._isource, pe.rva_to_file_offset(pdispatch_table + #{i * ptr_len})).unpack('#{format}')[0]"
begin
dispatch_funcs << eval(code)
rescue StandardError
next
end
end
end
dispatch_funcs
end
|
#reconstruct_disptbl_for_midl_server_info(pe, midl_server_info, count) ⇒ Object
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 911
def reconstruct_disptbl_for_midl_server_info(pe, midl_server_info, count)
rva = pe.vma_to_rva(midl_server_info['dispatchTable'].value)
server_routines = []
if pe.ptr_32?
count.times do
server_routines << read_dword(pe._isource, pe.rva_to_file_offset(rva)).unpack('V')[0]
rva += 4
end
else
count.times do
server_routines << read_qword(pe._isource, pe.rva_to_file_offset(rva)).unpack('Q<')[0]
rva += 8
end
end
server_routines
end
|
#reconstruct_disptbl_for_server_interface(pe, rpc_server_interface) ⇒ Object
870
871
872
873
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 870
def reconstruct_disptbl_for_server_interface(pe, rpc_server_interface)
rva = pe.vma_to_rva(rpc_server_interface['dispatchTable'].value)
reconstruct_disptbl_from_addr(pe, rva)
end
|
#reconstruct_disptbl_from_addr(pe, addr) ⇒ Object
875
876
877
878
879
880
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 875
def reconstruct_disptbl_from_addr(pe, addr)
rpc_dispatch_table = make_rpc_dispatch_table_t(pe)
reconstruct_struct_from_pe(pe, addr, rpc_dispatch_table)
rpc_dispatch_table
end
|
#reconstruct_endpoint_info(pe, server_if) ⇒ Object
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 794
def reconstruct_endpoint_info(pe, server_if)
endpoints = []
if (count = server_if['rpcProtseqEndpointCount'].value) > 0
rva = pe.vma_to_rva(server_if['rpcProtseqEndpoint'].value)
count.times do |i|
ep = make_rpc_protseq_endpoint(pe)
reconstruct_struct_from_pe(pe, rva+i*ep.slength, ep)
pprotseq = pe.vma_to_file_offset(ep['rpcProtocolSequence'].value)
pendpoint = pe.vma_to_file_offset(ep['endpoint'].value)
protseq = TurboRex::MSRPC::Utils.read_cstring(pe._isource, pprotseq)[0]
ep_name = TurboRex::MSRPC::Utils.read_cstring(pe._isource, pendpoint)[0]
endpoints << {protseq: protseq, ep_name: ep_name}
i+=ep.slength
end
end
endpoints
end
|
#reconstruct_midl_server_info(pe, rpc_server_interface) ⇒ Object
851
852
853
854
855
856
857
858
859
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 851
def reconstruct_midl_server_info(pe, rpc_server_interface)
if validate_rpc_server_interface(pe, rpc_server_interface) && has_interpreter_info?(rpc_server_interface)
rva = pe.vma_to_rva(rpc_server_interface['interpreterInfo'].value)
midl_server_info = make_midl_server_info(pe)
reconstruct_struct_from_pe(pe, rva, midl_server_info)
midl_server_info
end
end
|
#reconstruct_midl_stub_desc(pe, midl_server_info) ⇒ Object
861
862
863
864
865
866
867
868
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 861
def reconstruct_midl_stub_desc(pe, midl_server_info)
unless midl_server_info['pStubDesc'].value == 0
rva = pe.vma_to_rva(midl_server_info['pStubDesc'].value)
midl_stub_desc = make_midl_stub_desc(@pe)
reconstruct_struct_from_pe(pe, rva, midl_stub_desc)
midl_stub_desc if validate_midl_stub_desc(pe, midl_stub_desc)
end
end
|
#reconstruct_midl_syntax_info(pe, midl_server_info) ⇒ Object
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 825
def reconstruct_midl_syntax_info(pe, midl_server_info)
pSyntaxInfo = midl_server_info['pSyntaxInfo'].value
count = midl_server_info['nCount'].value
return nil if count < 0
syntax_infos = []
if pe.ptr_32?
len = TurboRex::MSRPC::RPCBase::MIDL_SYNTAX_INFO32.make(pack: 4, align: true).slength
else
len = TurboRex::MSRPC::RPCBase::MIDL_SYNTAX_INFO64.make(pack: 8, align: true).slength
end
unless pSyntaxInfo == 0
count.times do |i|
rva = pe.vma_to_rva(pSyntaxInfo + i * len)
midl_syntax_info = make_midl_syntax_info(pe)
reconstruct_struct_from_pe(pe, rva, midl_syntax_info)
syntax_infos << midl_syntax_info
end
end
syntax_infos
end
|
#reconstruct_offset_table(pe, server_if) ⇒ Object
775
776
777
778
779
780
781
782
783
784
785
786
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 775
def reconstruct_offset_table(pe, server_if)
if server_if['interpreterInfo'].value != 0
server_info = reconstruct_midl_server_info(pe, server_if)
unless server_info.nil?
pdisptbl = pe.vma_to_rva(server_if['dispatchTable'].value)
disptbl = reconstruct_disptbl_from_addr(pe, pdisptbl)
reconstruct_offset_table2(pe, disptbl, server_info)
end
end
end
|
#reconstruct_offset_table2(pe, disptbl, midl_server_info) ⇒ Object
788
789
790
791
792
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 788
def reconstruct_offset_table2(pe, disptbl, midl_server_info)
poffset_table = pe.vma_to_file_offset(midl_server_info['fmtStringOffset'].value)
count = disptbl['dispatchTableCount'].value
pe._isource.read(poffset_table, count).unpack('C'*count)
end
|
#reconstruct_struct_from_pe(pe, rva, cstruct) ⇒ Object
769
770
771
772
773
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 769
def reconstruct_struct_from_pe(pe, rva, cstruct)
length = cstruct.slength
data = pe._isource.read(pe.rva_to_file_offset(rva), length)
cstruct.from_s data
end
|
#reconstruct_stubless_pinfo(pe, client_if) ⇒ Object
817
818
819
820
821
822
823
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 817
def reconstruct_stubless_pinfo(pe, client_if)
proxy_info = make_midl_stubless_proxy_info(pe)
pinterpreter_info = client_if.InterpreterInfo_Value
rva = pe.vma_to_rva(pinterpreter_info)
reconstruct_struct_from_pe(pe, rva, proxy_info)
proxy_info if validate_stubless_proxy_info(pe, proxy_info)
end
|
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 936
def scan_xrefs_immediate(addr, dasm = nil)
dasm ||= (@dasm || new_dasm)
cpu_size = dasm.cpu.size
mask = (1 << cpu_size) - 1
format = (cpu_size == 64 ? 'q' : 'V')
res = []
dasm.sections.sort.each do |start_addr, encoded_data|
raw = encoded_data.data.to_str
(0..raw.length - cpu_size / 8).each do |offset|
data = raw[offset, cpu_size / 8].unpack(format).first
res << (start_addr + offset) if data == addr
end
end
res
end
|
#validate_midl_stub_desc(pe, struct) ⇒ Object
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 727
def validate_midl_stub_desc(pe, struct)
pfnAllocate = struct['pfnAllocate'].value
pfnFree = struct['pfnFree'].value
phandle = struct['implicit_handle_info'].value
bounds_flag = struct['fCheckBounds'].value
pointer_check = pe.valid_vma?(pfnAllocate) && pe.valid_vma?(pfnFree)
bounds_flag_check = (bounds_flag == 1 || bounds_flag == 0)
pointer_check && bounds_flag
end
|
#validate_rpc_server_interface(pe, rpc_server_interface) ⇒ Object
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 695
def validate_rpc_server_interface(pe, rpc_server_interface)
length = rpc_server_interface.slength
return false unless rpc_server_interface['length'].value == length
unless validate_transfer_syntax(rpc_server_interface['transferSyntax'])
return false
end
itpInfo = rpc_server_interface['interpreterInfo'].value if itpInfo == 0
else
section = pe._find_section_by_rva(pe.vma_to_rva(itpInfo))
return false if section.nil?
return false unless TurboRex::PEFile::Scanner.data_section?(section)
end
dispTable = rpc_server_interface['dispatchTable'].value
unless dispTable == 0
section = pe._find_section_by_rva(pe.vma_to_rva(dispTable))
return false if section.nil?
return false unless TurboRex::PEFile::Scanner.data_section?(section)
end
true
end
|
#validate_server_interface_from_pe(pe, address) ⇒ Object
721
722
723
724
725
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 721
def validate_server_interface_from_pe(pe, address)
make_rpc_server_interface(pe)
reconstruct_struct_from_pe(pe, address, rpc_server_interface)
validate_rpc_server_interface(pe, rpc_server_interface)
end
|
#validate_stubless_proxy_info(pe, stubless_proxy_info, strict_check = true) ⇒ Object
The “strict_check” option will use the algorithm of NdrClientCall3
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 743
def validate_stubless_proxy_info(pe, stubless_proxy_info, strict_check = true)
pTransferSyntax = stubless_proxy_info['pTransferSyntax'].value
pSyntaxInfo = stubless_proxy_info['pSyntaxInfo'].value
nCount = stubless_proxy_info['nCount'].value
dce_transfer = DCE_TransferSyntax.to_s
ndr64_transfer = NDR64_TransferSyntax.to_s
len = make_midl_syntax_info(pe).slength
return false if pTransferSyntax == 0
transfer_syntax = pe._isource.read(pe.vma_to_file_offset(pTransferSyntax), DCE_TransferSyntax.slength)
unless transfer_syntax == dce_transfer || transfer_syntax == ndr64_transfer
return false
end
if strict_check
nCount.times do |i|
syntaxinfo_trans = pe._isource.read(pe.vma_to_file_offset(pSyntaxInfo + i * len), DCE_TransferSyntax.slength)
break if syntaxinfo_trans == transfer_syntax
return false if i + 1 == nCount
end
end
true
end
|
#validate_transfer_syntax(transfer_syntax) ⇒ Object
691
692
693
|
# File 'lib/turborex/msrpc/rpcfinder.rb', line 691
def validate_transfer_syntax(transfer_syntax)
transfer_syntax.to_s == DCE_TransferSyntax.to_s || transfer_syntax.to_s == NDR64_TransferSyntax.to_s
end
|