因为要手工导入API,因此先定位到IAT:
IMPORT_DIRECTORY
RVA:3778
size:8c
处在rdata(rva:3000,大小cf4),文件偏移(1600,大小e00)
相对区段偏移:3778-3000=778,那么实际文件FOA:1600+778=1d78
由于原来所在的IAT表不足以容纳新增的API,因此
新增一个区段:(加一个导入函数即加一个import disciptor大小
.add
voffset vsize Roffset rsize
6000 8c+0x14 3200 200
新的IMPORT_DIRECTORY,设定DLL和API字符串的FOA:
RVA:
size=a0
"USER32.DLL" FOA:22F9
"MessageBoxExA" FOA:2303(包含序号Hint)
origial timedatastamp forwarchain name firstthunk
60xx 00000 00000 60xx 60xx
FOA:32a0 32a8
RVA:60A0 60A8
先在文件处3278填上0x14字节的f作为标记,最後结束刚好是0x14个0,那麽我将orignal first thunk
字段的RVA设在32a0
然後写original first thunk,在32a0处,写上(MessageBoxExA的FOA)2303(RVA:?????)
2303处於rdata段,则RVA=3000+230a-1600=3D0A
DLL name的FOA:22F9
22F9处於rdata 段,则RVA=3000+22F9-1600=3cf9
为了方便,first thunkdata(RVA就写在original first thunk後面),
则为FOA为:32A4,其RVA=60A4
最後,用工具将numberOfSections和sizeOfImage这2个字段分别改为5,和7000(所有区段的虚拟大小+头虚拟大小,以内存对齐粒度对齐)
找到按钮事件,因为MessageBox需要4个参数,这样:
push MB_OK
push szCaption
push szContent
push NULL //hwnd为空,为了方便
CALL [XXXXX]
起初我不会加这种东东,添加什麽指令系统会帮填充IAT呢?於是记得PE权威指南,里面第一章有个HELLOWORLD,
好,就从最简单的分析起.
在PE权威指南里,第一章,用WINHEX看了下,可以看到CALL MESSAGEBOX的位置正好是firstthunk的RVA
於是我这里仿照它来改入,看到论坛上的人都是用shellcode,呵呵,我不懂,迟点再学,
现在手功构造这个函数
为了方便,直接在OD中修改指令:
FF 15 A8 60 40
FF 15 是CALL[XXXX]的形式,但这里我不清楚40是否是固定的
继续找地方放数据,在.data段0的位置找起:
szCaption:(FOA)2570 RVA:2570-2400+4000=4170
szContent:(FOA)2578 RVA:2578-2400+4000=4178
由於试验过在按钮的地方要把全部指令写入,地方不够,
0040216E 6A 00 push 0x0 从这里写些代码:
於是:
00401613 /E9 550B0000 jmp 0040216D
先跳到PATCH区,然後写代码:
0040216D > \60 pushad ; |
0040216E . 6A 00 push 0x0 ; |Style = MB_OK|MB_APPLMODAL
00402170 68 70414000 push 00404170 ; ASCII "HelloPE"
00402175 68 78414000 push 00404178 ; ASCII "pklong007"
0040217A . 6A 00 push 0x0 ; |hOwner = NULL
0040217C . FF15 A8604000 call dword ptr [<&USER32.MessageBoxEx>; \MessageBoxExA
00402182 . 61 popad
00402183 . C3 retn
60 6A 00 68 70 41 40 00 68 78 41 40 00 6A 00 FF 15 A8 60 40 00 61 C3
最後发现数据区被填了一些不知名的数据,貌似有个initterm函数把数据区赋了些值,字符串被冲掉了:
於是把新加入的区段大小改为0x100,在後面写入数据,直接在OD中修改:
004060e0 ->"HelloPE"
004060e8->"pklong007"
最终代码:
0040216D > \60 pushad ; |
0040216E . 6A 00 push 0x0 ; |Style = MB_OK|MB_APPLMODAL
00402170 68 E0604000 push 004060E0 ; ASCII "HelloPE"
00402175 68 E8604000 push 004060E8 ; ASCII "pklong007"
0040217A 6A 00 push 0x0
0040217C FF15 A8604000 call dword ptr [<&USER32.MessageBoxEx>; user32.MessageBoxExA
00402182 . 61 popad
00402183 . C3 retn
IMPORT_DIRECTORY
RVA:3778
size:8c
处在rdata(rva:3000,大小cf4),文件偏移(1600,大小e00)
相对区段偏移:3778-3000=778,那么实际文件FOA:1600+778=1d78
由于原来所在的IAT表不足以容纳新增的API,因此
新增一个区段:(加一个导入函数即加一个import disciptor大小
.add
voffset vsize Roffset rsize
6000 8c+0x14 3200 200
新的IMPORT_DIRECTORY,设定DLL和API字符串的FOA:
RVA:
size=a0
"USER32.DLL" FOA:22F9
"MessageBoxExA" FOA:2303(包含序号Hint)
origial timedatastamp forwarchain name firstthunk
60xx 00000 00000 60xx 60xx
FOA:32a0 32a8
RVA:60A0 60A8
先在文件处3278填上0x14字节的f作为标记,最後结束刚好是0x14个0,那麽我将orignal first thunk
字段的RVA设在32a0
然後写original first thunk,在32a0处,写上(MessageBoxExA的FOA)2303(RVA:?????)
2303处於rdata段,则RVA=3000+230a-1600=3D0A
DLL name的FOA:22F9
22F9处於rdata 段,则RVA=3000+22F9-1600=3cf9
为了方便,first thunkdata(RVA就写在original first thunk後面),
则为FOA为:32A4,其RVA=60A4
最後,用工具将numberOfSections和sizeOfImage这2个字段分别改为5,和7000(所有区段的虚拟大小+头虚拟大小,以内存对齐粒度对齐)
找到按钮事件,因为MessageBox需要4个参数,这样:
push MB_OK
push szCaption
push szContent
push NULL //hwnd为空,为了方便
CALL [XXXXX]
起初我不会加这种东东,添加什麽指令系统会帮填充IAT呢?於是记得PE权威指南,里面第一章有个HELLOWORLD,
好,就从最简单的分析起.
在PE权威指南里,第一章,用WINHEX看了下,可以看到CALL MESSAGEBOX的位置正好是firstthunk的RVA
於是我这里仿照它来改入,看到论坛上的人都是用shellcode,呵呵,我不懂,迟点再学,
现在手功构造这个函数
为了方便,直接在OD中修改指令:
FF 15 A8 60 40
FF 15 是CALL[XXXX]的形式,但这里我不清楚40是否是固定的
继续找地方放数据,在.data段0的位置找起:
szCaption:(FOA)2570 RVA:2570-2400+4000=4170
szContent:(FOA)2578 RVA:2578-2400+4000=4178
由於试验过在按钮的地方要把全部指令写入,地方不够,
0040216E 6A 00 push 0x0 从这里写些代码:
於是:
00401613 /E9 550B0000 jmp 0040216D
先跳到PATCH区,然後写代码:
0040216D > \60 pushad ; |
0040216E . 6A 00 push 0x0 ; |Style = MB_OK|MB_APPLMODAL
00402170 68 70414000 push 00404170 ; ASCII "HelloPE"
00402175 68 78414000 push 00404178 ; ASCII "pklong007"
0040217A . 6A 00 push 0x0 ; |hOwner = NULL
0040217C . FF15 A8604000 call dword ptr [<&USER32.MessageBoxEx>; \MessageBoxExA
00402182 . 61 popad
00402183 . C3 retn
60 6A 00 68 70 41 40 00 68 78 41 40 00 6A 00 FF 15 A8 60 40 00 61 C3
最後发现数据区被填了一些不知名的数据,貌似有个initterm函数把数据区赋了些值,字符串被冲掉了:
於是把新加入的区段大小改为0x100,在後面写入数据,直接在OD中修改:
004060e0 ->"HelloPE"
004060e8->"pklong007"
最终代码:
0040216D > \60 pushad ; |
0040216E . 6A 00 push 0x0 ; |Style = MB_OK|MB_APPLMODAL
00402170 68 E0604000 push 004060E0 ; ASCII "HelloPE"
00402175 68 E8604000 push 004060E8 ; ASCII "pklong007"
0040217A 6A 00 push 0x0
0040217C FF15 A8604000 call dword ptr [<&USER32.MessageBoxEx>; user32.MessageBoxExA
00402182 . 61 popad
00402183 . C3 retn
最后,WIN7和XP都能正常弹出,且点击多次也不崩。