能力值:
( LV12,RANK:530 )
6 楼
很有趣吗?下面是我弄的,但是我对键盘消息处理不大熟悉!!!
下面是窗口过程地址:
窗口过程的一般形式如下: procdlgmain proc hwnd ,wmsg,wparam,lparam
//看下面代码就知道
//hwnd=[ebp+8]
//wmsg=[ebp+C]
//wparam=[ebp+10]
那么lparam应该=[ebp+14]
00401171 . 55 push ebp
00401172 . 8BEC mov ebp, esp
00401174 . 817D 0C 10010>cmp dword ptr [ebp+C], 110 //比较是不是WM_KEYFIRST消息,也就是你按下了哪个键
0040117B 75 4C jnz short 004011C9
0040117D . FF35 74314000 push dword ptr [403174] ; /lParam = 0
00401183 . 6A 01 push 1 ; |wParam = 1
00401185 . 68 80000000 push 80 ; |Message = WM_SETICON
0040118A . FF75 08 push dword ptr [ebp+8] ; |hWnd
0040118D . E8 B8000000 call <jmp.&user32.SendMessageA> ; \SendMessageA
00401192 . 6A 02 push 2 ; /ControlID = 2 从这里看出退出ID=2
00401194 . FF75 08 push dword ptr [ebp+8] ; |hWnd
00401197 . E8 9C000000 call <jmp.&user32.GetDlgItem> ; \GetDlgItem
0040119C . A3 78314000 mov dword ptr [403178], eax 句柄保存到[403178]
004011A1 . 6A 00 push 0 //这里改为1就显示出来拉!~
004011A3 . FF35 78314000 push dword ptr [403178]
004011A9 . 74 12 je short 004011BD
004011AB . 75 10 jnz short 004011BD ;相当与jmp
004011AD . 57 push edi
004011AE . 65:6C ins byte ptr es:[edi], dx //感觉这里是留给我们添加响应F6的代码的
004011B0 . 636F 6D arpl word ptr [edi+6D], bp 但是我对键盘处理不熟,等答案好了//
004011B3 . 65:20746F 20 and byte ptr gs:[edi+ebp*2+20], dh
004011B8 . 44 inc esp
004011B9 . 46 inc esi
004011BA . 43 inc ebx
004011BB . 47 inc edi
004011BC 21 db 21 ; CHAR '!'
004011BD . B8 58124000 mov eax, 00401258 ; |
004011C2 . 83E8 08 sub eax, 8 ; |参数在上面呢
004011C5 . FFD0 call eax ; \ShowWindow
004011C7 . EB 3F jmp short 00401208
004011C9 > 817D 0C 11010>cmp dword ptr [ebp+C], 111 ;比较是不是按妞的消息了
004011D0 . 75 26 jnz short 004011F8
004011D2 . 837D 10 01 cmp dword ptr [ebp+10], 1 是不是按了about拉?
004011D6 . 75 16 jnz short 004011EE
004011D8 . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004011DA . 68 13314000 push 00403113 ; |Title = "ty123's Reverseme #1, Level: 1/10"
004011DF . 68 00304000 push 00403000 ; |Text = TAB,TAB,"编?,B4,":
ty123",CR,LF,CR,LF,"说?,F7,": 这是为庆",D7,"DFCG论坛顺利",BB,"?,B8,"",B4,"",D7,"",A8,"门编?,B4,"的 ;-)",CR,LF,CR,LF,"1.
",B4,"",B0,"体中有?,BB,"",B8,"鲆?,B2,"?,B0,"",B4,"钮?,AC,"",BD,"",AB,"它显示出?,B4,"",B2...
004011E4 . FF75 08 push dword ptr [ebp+8] ; |hOwner
004011E7 . E8 58000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
004011EC . EB 1A jmp short 00401208
004011EE > 837D 10 02 cmp dword ptr [ebp+10], 2 ;你是不是按了退出拉?
004011F2 . 75 14 jnz short 00401208
004011F4 . EB 00 jmp short 004011F6
004011F6 > EB 10 jmp short 00401208 //改成EB16就可以拉,因为向前跳16h字节就是ExitProcess呀
004011F8 > 837D 0C 10 cmp dword ptr [ebp+C], 10
004011FC . 75 0A jnz short 00401208
004011FE . 6A 00 push 0 ; /Result = 0
00401200 . FF75 08 push dword ptr [ebp+8] ; |hWnd
00401203 . E8 2A000000 call <jmp.&user32.EndDialog> ; \EndDialog
00401208 > 33C0 xor eax, eax
0040120A . C9 leave
0040120B . C2 1000 retn 10
能力值:
( LV2,RANK:10 )
8 楼
这是我2003年初写的东西,给没有思路的道友参考一下。当然,方法不止这一个,但比这个还笨的方法估计是没有了,呵呵。 2. Set a system Hotkey for F7
---------------------------------------
The hotkey of F7 shall be registered prior to use it by means of WM_HOTKEY (equ=312h).
In order to insert RegisterHotKey function, the import table address shall be found firstly.
...
00000140 58200000 DD 00002058 ; Import Table address = 2058
00000144 50000000 DD 00000050 ; Import Table size = 50
...
00000198 00200000 DD 00002000 ; Import Address Table address = 2000
0000019C 58000000 DD 00000058 ; Import Address Table size = 58
...
So, let's go to 0x2058 and search the IMAGE_IMPORT_DESCRIPTOR of USER32.DLL.
.0040206C: -E8 20 00 00
.00402070: 00 00 00 00-00 00 00 00-E2 21 00 00-40 20 00 00
where,
E8 20 00 00 ; OriginalFirstThunk
00 00 00 00 ; TimeDateStamp
00 00 00 00 ; ForwarderChain
E2 21 00 00 ; Name (the address of USER32.DLL)
40 20 00 00 ; FirstThunk
Well, we are in condition to insert RegisterHotKey function. It is a quite complicated task for me. I have to insert 4 bytes at 0x2054, another 4 bytes at 0x20FC, and 17 bytes before 0x21ED for the mentioned function name, then delete 4+4+17 bytes so as to maintain the section size, and then revise all the related function's RVA accordingly (Is there any simple method other than creat a new section for RegisterHotKey?). Only the important parts is copied in the following:
Revising RVA of functions of USER32.dll
DialogBoxParamA 9A 21 --> A2 21 (RVA=204Ch)
EndDialog AC 21 --> B4 21 (RVA=2050h)
LoadIconA B8 21 --> C0 21 (RVA=2048h)
MessageBoxA C4 21 --> CC 21 (RVA=2044h)
SendMessageA D2 21 --> DA 21 (RVA=2040h)
RegisterHotKey --> E9 21 (RVA=2054h)
Revising RVA of functions of KERNEL32.dll
WriteFile 2C 22 --> 45 22 (RVA=2028h)
GetModuleHandleA 18 22 --> 31 22 (RVA=2038h)
ExitProcess 0A 22 --> 23 22 (RVA=202Ch)
CreateFileA FC 21 --> 15 22 (RVA=2030h)
CloseHandle EE 21 --> 07 22 (RVA=2034h)
Revising RVA of functions of GDI32.dll
SelectObject 80 21 --> 88 21 (RVA=2020h)
GetDeviceCaps 70 21 --> 78 21 (RVA=201Ch)
GetDIBColorTable 5C 21 --> 64 21 (RVA=2018h)
DeleteObject 4C 21 --> 54 21 (RVA=2000h)
DeleteDC 40 21 --> 48 21 (RVA=2010h)
CreateDIBSection 2C 21 --> 34 21 (RVA=200Ch)
CreateDCA 20 21 --> 28 21 (RVA=2008h)
CreateCompatibleDC 0A 21 --> 12 21 (RVA=2004h)
BitBlt 00 21 --> 08 21 (RVA=2014h)
Repairing IMAGE_IMPORT_DESCRIPTOR of USER32.DLL
.0040206C: -E8 20 00 00
.00402070: 00 00 00 00-00 00 00 00-E2 21 00 00-40 20 00 00
|
v
.00402070: EC 20 00 00-00 00 00 00-00 00 00 00-FB 21 00 00
.00402080: 40 20 00 00-
Repairing IMAGE_IMPORT_DESCRIPTOR of KERNEL32.dll
.00402080: D0 20 00 00-00 00 00 00-00 00 00 00-38 22 00 00
.00402090: 28 20 00 00-
|
v
.00402084: -D4 20 00 00-00 00 00 00-00 00 00 00
.00402090: 51 22 00 00-28 20 00 00-
Repairing IMAGE_IMPORT_DESCRIPTOR of GDI32.dll
.00402058: -A8 20 00 00-00 00 00 00
.00402060: 00 00 00 00-90 21 00 00-00 20 00 00-
|
v
.0040205C: -AC 20 00 00
.00402060: 00 00 00 00-00 00 00 00-98 21 00 00-00 20 00 00
Repairing IMAGE_DIRECTORY_ENTRY_IMPORT as follows
00000140: 5C 20 00 00-50 00 00 00
Repairing IMAGE_DIRECTORY_ENTRY_IAT as follows
00000198: -00 20 00 00-5C 00 00 00
Wow, god, the function of RegisterHotKey has been eventually inserted! Let's switch to code section to make F7 working.
===========================================================
mov eax,uMsg
.if eax==WM_INITDIALOG ; equ=110h
invoke RegisterHotKey,hWin,01h,NULL,076h ; Register F7 (076h)
.elseif eax==WM_HOTKEY ; equ=312h
.....(capture) ;
.elseif eax==WM_CLOSE ; equ=10h
invoke EndDialog,hWin,0
===========================================================
the above is one of the solution how to register and use hotkey of F7.
能力值:
(RANK:520 )
12 楼
非常感谢老神树大侠提供的宝贵资料,我没google到全文.
不懂,pe格式,一边盯着大侠的文章看,一般查pe格式相关资料,对于文章描述的主要内容终于有所领会,只是有两个问题,搞不明白,请赐教!
大侠文章中提到以下内容:
Well, we are in condition to insert RegisterHotKey function. It is a quite complicated task for me. I have to insert 4 bytes at 0x2054, another 4 bytes at 0x20FC, and 17 bytes before 0x21ED for the mentioned function name, then delete 4+4+17 bytes so as to maintain the section size,
1.insert 4 bytes at 0x2054,我觉得这里放hotkey函数名的偏移地址是吗?那么
another 4 bytes at 0x20FC,在0x20fc这个地方准备插入什么内容,为什么要 选在0x20fc这个地方呢?
2.and 17 bytes before 0x21ED for the mentioned function name,请问function name: RegisterHotKey 共14个字符,加结束字符'\0'共15个那么插入的17个字符,另外两个字符是什么呢?
我用16进制编辑工具看pe文件发现函数名前面都有两个字节的内容,并且后面有的有一个结束符\0有的有两个.
如果我把RegisterHotKey 这个字符串插入pe,它的前面是不是要填两个字节的内容呢,填什么内容呢?
非常感谢老神树的reversme很有收获.期待回复!
能力值:
( LV2,RANK:10 )
13 楼
非常感谢老神树大侠提供的宝贵资料,我没google到全文.
如Readme.txt中所讲,这是我2003年年初写的,没有在网上发布,所以你找不到,呵呵。
不懂,pe格式,一边盯着大侠的文章看,一般查pe格式相关资料,对于文章描述的主要内容终于有所领会,
祝贺netwind大侠步入Reverser行列!(或许您太谦虚啦,呵呵)
1.insert 4 bytes at 0x2054,我觉得这里放hotkey函数名的偏移地址是吗?那么another 4 bytes at 0x20FC,在0x20fc这个地方准备插入什么内容,为什么要 选在0x20fc这个地方呢?
文章是针对另外一个程序所写的,所以地址跟Reverseme1不合。
2.and 17 bytes before 0x21ED for the mentioned function name,请问function name: RegisterHotKey 共14个字符,加结束字符'\0'共15个那么插入的17个字符,另外两个字符是什么呢?
弄清楚它,先要了解IMAGE_IMPORT_BY_NAME结构,我们一起来学习学习...
IMAGE_IMPORT_BY_NAME STRUCT
Hint dw ?
Name1 db ?
IMAGE_IMPORT_BY_NAME ENDS
结构中的Hint字段(dw是一个word,也就是两个bytes)可以表示函数的序号,不过有些编译器总将它置为0。你可以试试,从PE文件中随便找一个函数,将这两个字节改为0,你会发现程序照样运行,不受其影响。为什么呢?因为在程序编译时,编译器将IMAGE_THUNK_DATA(double word)的最高位置为0,也就是表示函数以字符串类型的函数名方式导入,这是IMAGE_THUNK_DATA这个双字(double word)的值就是一个RVA。
我用16进制编辑工具看pe文件发现函数名前面都有两个字节的内容,并且后面有的有一个结束符\0有的有两个.
从前一个问题的分析,你就明白:有2个\0的原因是下一个函数的Hint字段首字节为\0。
如果我把RegisterHotKey 这个字符串插入pe,它的前面是不是要填两个字节的内容呢,填什么内容呢?
如上所述,这里随便填(填上女朋友的名字?呵呵)。
不知道我说明白了没有,建议在网上找一个PE文件格式的资料看看。
PS:玩过RM1和RM2的道友知道,Reverseme1玩的是导入表;Reverseme2玩的是导出表;Reverseme3呢?......
能力值:
(RANK:520 )
14 楼
非常感谢老神树大侠详细的指导,问题弄明白了.
中间有些新的疑问,劳请大侠指点.
以大侠提供的资料为参考,我感觉这个reverseme 插入热键时 主要做以下事情:
1.插入RegisterHotKey这个函数名.
2.插入函数名的偏移地址.(rva)
3.修改对应的rva表
4.修改import table和IAT的rva.
按您提供的资料在user32.dll的rva表里插入了RegisterHotKey.
这样其他函数rva都要相应改变.有一定的工作量.
然后我把 4st0ne 大侠修改后的reverseme拿来分析,4st0ne 大侠用loadpe插入的RegisterHotKey,发现它在pe文件结尾插入了user32.dll,RegisterHotKey
接着插入了kernel32.dll引用的函数的rva 表,user32.dll(原来的user32.dll)引用的函数的rva表以及新插入的user32.dll引用的函数的rva表.
最后修改了import table 的rva 修改为pe结尾kernel32表开始的地方,这样载入pe时,它将读入三个表.把RegisterHotKey读入进去.
kernel32.dll
exitprocess
user32.dll
ShowWindow
....
user32.dll
RegisterHotKey
用pe工具会看到三个dll 如上所示.
这时pe文件结尾有如下内容:
00 00 00 00 00 00 00 00 75 73 65 72 33 32 2E 64
6C 6C 00 00 00 52 65 67 69 73 74 65 72 48 6F 74
4B 65 79 00 0B 50 00 00 00 00 00 00 74 20 00 00
00 00 00 00 00 00 00 00 00 21 00 00 00 20 00 00
8C 20 00 00 00 00 00 00 00 00 00 00 7A 21 00 00
18 20 00 00 1C 50 00 00 00 00 00 00 00 00 00 00
00 50 00 00 1C 50 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00
二进制对应字符如下:
00000ff0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00001000h: 75 73 65 72 33 32 2E 64 6C 6C 00 00 00 52 65 67 ; user32.dll...Reg //这里插入的是user32.dll名
00001010h: 69 73 74 65 72 48 6F 74 4B 65 79 00 0B 50 00 00 ; isterHotKey..P.. 这里插入的是函数名
00001020h: 00 00 00 00 74 20 00 00 00 00 00 00 00 00 00 00 ; ....t .......... //这里开始插入三个rva表.
00001030h: 00 21 00 00 00 20 00 00 8C 20 00 00 00 00 00 00 ; .!... ..?......
00001040h: 00 00 00 00 7A 21 00 00 18 20 00 00 1C 50 00 00 ; ....z!... ...P..
00001050h: 00 00 00 00 00 00 00 00 00 50 00 00 1C 50 00 00 ; .........P...P..
00001060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
整理出三个表如下:
kernel32.dll :
OriginalFirstThunk:2074
TimeDateStampe:0000
ForwarDerChain:0000
Name:2100
FirstThunk:2000
user32.dll:
208c
0000
0000
217a
2018
user32.dll:(这个是插入的)
501c //这个地址指向500b,500b指向RegisterHotKey函数名前面两字节.
0000
0000
5000//这个指向user32.dll名
501c
前面两个表pe文件已经存在,在2038的地方,2038就是这个程序import table的rva
我们插入时 先插入字符串user32.dll和结束字符0
然后 插入RegisterHotKey这个字符串,根据大侠的指点,其前面要插入两字节的内容,可以为任意值,插入后在结尾插入结束符0.
然后插入RegisterHotKey的rva(用pe工具点中RegisterHotKey可看到其偏移长度500b)留四个0字节(根据原pe的内容)再依次输入
74 20 00 00--------->这里四个字节偏移为5024.把5024作为新的import table的rva
00 00 00 00 00 00 00 00 00 21 00 00 00 20 00 00
8C 20 00 00 00 00 00 00 00 00 00 00 7A 21 00 00
18 20 00 00 这是程序原来两个rva表的内容.
接着插入我们 定义的user32.dll表,
根据原pe文件,在import table 的rva-8的地方放的是起始函数的偏移.
这里把import table改为5024后 就是在501c的地方放 的是起始函数偏移,这里就是RegisterHotKey的rva.就是500b.指向它前面两字节.
那么对于这里的user32.dll表OriginalFirstThunk我们就填501c.
接着
TimeDateStampe:0000
ForwarDerChain:0000
再填
5000//这个是user32.dll名 的偏移.
501c//这个指向RegisterHotKey函数名前面两个字节
好了填完了.以上rva都占四字节也就是比如填501c时应该这样:1c 50 00 00
找到指向import table rva的地方,
38 20 00 00 3C 00 00 00 //显示import table rva为2038, 大小 :3c
我们改为24 50 00 00 3c 00 00 00.
好了所有的修改都完成了.保存文件.(上面所列出的rva值是4st0ne 大侠修改后的程序里的。自己手工修改时,相应的都做了合适的改变)
这手工修改完毕,运行文件却提示出错,用pe工具查看,多了一个user32.dll 且里面有RegisterHotKey这个函数。但程序却不能正确执行。
我用od载入程序发现存放 RegisterHotKey偏移长度500b的地方,也就是OriginalFirstThunk 501c指向的地方,4st0ne 大侠修改后的程序里 被换成了77d3678b(RegisterHotKey在user32.dll里的实际地址),而我手工修改的程序里却没变。
不知道哪里出问题了,手工修改过来的运行出错,我可以肯定,修改后rav都是一一对应的,由修改后的import table出发都能定位到相应的函数。可就是搞不明白为什么出错。
另外中间有成功运行过一次,那次我把importa table rva改后 把IAT 保留原来的值00 20 00 00 38 00 00 00 结果成功运行了,只是用od加载到程序里时同样存放 RegisterHotKey偏移长度500b的地方没被真实的RegisterHotKey的地址覆盖。后来把这个给改的出错了。
再后来,我再尝试手工在pe结尾插入rva表,保存后都不能正常运行。
这个东西可能表达起来有点乱,请老神树大侠看看我描述的整个过程,哪里有问题,谢谢!
再次感谢老神树大侠。以前也曾想学pe格式,结果一看到庞大的长篇文字,越看越迷糊,通过老神树大侠这个reverseme的学习并参考您提供的资料,感觉对引入表这一块有所收获。
找到了学习pe的一把钥匙,谢谢!希望后面有更精彩的reverseme 以及破解分析文章。
Ps:4st0ne 大侠,reverseme的破文很精彩,学习了,谢谢!
能力值:
( LV2,RANK:10 )
16 楼
Originally posted by netwind 中间有些新的疑问,.......
问题找到了吗?把你有问题的修改程序发到我的信箱或发到这里。
能力值:
(RANK:520 )
17 楼
这个是我修改的文件,把函数名和rva表都加在了pe的最后,麻烦您看下.
非常感谢,觉得玩reverseme让对学pe的兴趣很浓厚.
今晚做车回老家了,可能要离开电脑一周了.
祝福老神树大侠新年快乐.
感谢kanxue提供如此一个有浓厚技术氛围的交流环境!
祝福论坛每一网友新年快乐!
上传的附件: