TA的每日心情 | 奋斗 2016-1-13 12:25 |
---|
签到天数: 3 天 [LV.2]偶尔看看I
|
【文章标题】: PEdiy RoboForm2Go 密码管理软件
【文章作者】: 小Q
【作者邮箱】: [email protected]
【作者主页】: http://www.hookdll.com
【作者QQ号】: no
【软件名称】: RoboForm2Go
【软件大小】: 2m多
【下载地址】: http://www.roboform.com/cn/pass2go.html
【加壳方式】: 无
【保护方式】: 无
【编写语言】: 未知
【使用工具】: OD与PE工具
【操作平台】: Windows 8.1 64bit and xp 32bit test
【软件介绍】: RoboForm2Go是目前世界上最安全实用的密码管理软件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
3年多了,结婚来都没写过文章了,在工作后抽时间看了下软件并写下了这文章,作下记录,自己也是非常喜欢PEDIY,呵呵,大牛们可以直接略过。。。。。
一直在使用的密码管理软件,非常好用,有那么一天在国外网站发现了PC版的破解,但是就是没U盘版的,自己经常要换电脑使用,U盘到处插!这软件自然就好用了!
软件安装后,分析发现只要用破解后的roboform.dll和roboform-x64.dll在软件解压文件到缓存运行前替换掉这2个文件的话就可以解决问题!运行后就是破解好的!
一开始时想写个DLL完成这个过程的,可是在Windows 8.1 64bit运行出问题,后决定PE里DIY写代码,这样又省了挂一个DLL,可是PEDIY软件要解决的问题非常多!
1.要先获取roboform.dll和roboform-x64.dll所在盘的位置,这个好解决!用PEB找。。。
2.要复制到缓存,地址那么长!!汗,只有wsprintfW能解决问题!
3.最后用CopyFileW进行复制!
然后大问题来了,这软件要运行在32跟64位系统用的,保证兼容是个大问题!这API的获取可也是这大问题,还好可以利用0day知识里的Shellcode代码去动态获取API
大体过程:
在程序准备执行时堆栈:
- 0106FC00 7630495D 返回到 kernel32.7630495D-------------->这里是中一个调用返回
- 0106FC04 7E8F5000
- 0106FC08 /0106FC4C
复制代码 不说这么多了,看代码吧
第一处Patch
- 005071D8 > E8 C4B40000 CALL Portable.005126A1----> JMP Portable.00DE7961 ; PE开始执行的地方,看堆栈(上),返回在kernel32.dll的一个函数调用上
- 005071DD .^ E9 17FEFFFF JMP Portable.00506FF9
- 005071E2 CC INT3
- 005071E3 CC INT3
- 005071E4 CC INT3
- 005071E5 CC INT3
- 005071E6 CC INT3
复制代码 ////////////////////////////////子函数////////////////////////////////////////////////////////////////////////
- 00DE7900 33C0 /XOR EAX, EAX
- 00DE7902 |. AC |LODS BYTE PTR DS:[ESI] ; LODS到CopyFileW和LoadLibraryA字符串头
- 00DE7903 |. 85C0 |TEST EAX, EAX ; 0就是找到
- 00DE7905 |.^ 75 F9 |JNZ SHORT Portable.00DE7900
- 00DE7907 |. 51 |PUSH ECX
- 00DE7908 |. 52 |PUSH EDX
- 00DE7909 |. 56 |PUSH ESI
- 00DE790A |. 53 |PUSH EBX
- 00DE790B |. FFD2 |CALL NEAR EDX
- 00DE790D |. 5A |POP EDX
- 00DE790E |. 59 |POP ECX
- 00DE790F |. AB |STOS DWORD PTR ES:[EDI] ; 存到 >ASCII"GetProcAddress"开始的地方
- 00DE7910 |.^ E2 EE \LOOPD SHORT Portable.00DE7900
- 00DE7912 |. 33C0 XOR EAX, EAX
- 00DE7914 \. C3 RETN
复制代码- 00DE7915 . 47 65 74 50 7>ASCII "GetProcAddress",0 -------------->等下找到的API调用会存到此处!
- 00DE7924 . 43 6F 70 79 4>ASCII "CopyFileW",0 -------------->复制文件用的字符串
- 00DE792E . 4C 6F 61 64 4>ASCII "LoadLibraryA",0 -------------->用这个
- 00DE793B . 75 73 65 72 3>ASCII "user32.dll",0 -------------->和这个
- 00DE7946 . 77 73 70 72 6>ASCII "wsprintfW",0 -------------->生出wsprintfW
复制代码- 00DE7950 90 NOP
- 00DE7951 . E8 00000000 CALL Portable.00DE7956 ; 重定位
- 00DE7956 58 POP EAX
- 00DE7957 . 83E8 41 SUB EAX, 0x41 ; 加41的00DE7915是存API地址的地方
- 00DE795A . 50 PUSH EAX
- 00DE795B .- E9 9B5A0B00 JMP Portable.00E9D3FB
- 00DE7960 90 NOP
复制代码 //////////////////////////////////JMP Portable.00DE7961/////////////////////////////////////////////////////////////
- 00DE7961 > 60 PUSHAD ; 保存下寄存器
- 00DE7962 . FF7424 20 PUSH DWORD PTR SS:[ESP+0x20] ; 向堆下面取回:返回到 kernel32.7630495D
- 00DE7966 . 5A POP EDX
- 00DE7967 > 66:813A 4D5A CMP WORD PTR DS:[EDX], 0x5A4D ; 比较PE头
- 00DE796C . 74 06 JE SHORT Portable.00DE7974 ; -------------->kernel32.dll基地址找到后跳走
- 00DE796E . 4A DEC EDX
- 00DE796F . 66:31D2 XOR DX, DX
- 00DE7972 .^ EB F3 JMP SHORT Portable.00DE7967
- 00DE7974 > E8 00000000 CALL Portable.00DE7979 ; 重定位
- 00DE7979 58 POP EAX
- 00DE797A . 83E8 64 SUB EAX, 0x64 ; 指向 字符串>ASCII "GetProcAddress",0
- 00DE797D . 92 XCHG EAX, EDX ; 2个寄存器值交换下
- 00DE797E . 8BD8 MOV EBX, EAX ; 找到的 kernel32 基地址存入EBX
- 00DE7980 . 8B73 3C MOV ESI, DWORD PTR DS:[EBX+0x3C] ; kernel32.dll的PE头相对MZ的偏移
- 00DE7983 . 8B7433 78 MOV ESI, DWORD PTR DS:[EBX+ESI+0x78] ; 输出表地址
- 00DE7987 . 03F3 ADD ESI, EBX ; 转化成VA,记住esi=输出表VA
- 00DE7989 . 8B7E 20 MOV EDI, DWORD PTR DS:[ESI+0x20] ; AddressOfNames
- 00DE798C . 03FB ADD EDI, EBX ; 记住edi=AddressOfNames数组地址
- 00DE798E . 8B4E 14 MOV ECX, DWORD PTR DS:[ESI+0x14] ; NumberOfFunctions
- 00DE7991 . 33ED XOR EBP, EBP
- 00DE7993 . 56 PUSH ESI
- 00DE7994 > 57 PUSH EDI
- 00DE7995 . 51 PUSH ECX
- 00DE7996 . 8B3F MOV EDI, DWORD PTR DS:[EDI] ; 首个Name的VA
- 00DE7998 . 03FB ADD EDI, EBX
- 00DE799A . 8BF2 MOV ESI, EDX
- 00DE799C . 6A 0E PUSH 0xE
- 00DE799E . 59 POP ECX
- 00DE799F . F3:A6 REPE CMPS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI] ; 比较
- 00DE79A1 . 74 08 JE SHORT Portable.00DE79AB ; 如果找到就跳走
- 00DE79A3 . 59 POP ECX
- 00DE79A4 . 5F POP EDI
- 00DE79A5 . 83C7 04 ADD EDI, 0x4
- 00DE79A8 . 45 INC EBP
- 00DE79A9 .^ E2 E9 LOOPD SHORT Portable.00DE7994 ; 循环直到找到GetProcAddress
- 00DE79AB > 59 POP ECX
- 00DE79AC . 5F POP EDI
- 00DE79AD . 5E POP ESI
- 00DE79AE . 8BCD MOV ECX, EBP
- 00DE79B0 . 8B46 24 MOV EAX, DWORD PTR DS:[ESI+0x24]
- 00DE79B3 . 03C3 ADD EAX, EBX
- 00DE79B5 . D1E1 SHL ECX, 1
- 00DE79B7 . 03C1 ADD EAX, ECX
- 00DE79B9 . 33C9 XOR ECX, ECX
- 00DE79BB . 66:8B08 MOV CX, WORD PTR DS:[EAX]
- 00DE79BE . 8B46 1C MOV EAX, DWORD PTR DS:[ESI+0x1C]
- 00DE79C1 . 03C3 ADD EAX, EBX
- 00DE79C3 . C1E1 02 SHL ECX, 0x2
- 00DE79C6 . 03C1 ADD EAX, ECX
- 00DE79C8 . 8B00 MOV EAX, DWORD PTR DS:[EAX]
- 00DE79CA . 03C3 ADD EAX, EBX
- 00DE79CC . 8BFA MOV EDI, EDX
- 00DE79CE . 8BF7 MOV ESI, EDI
- 00DE79D0 . 83C6 0E ADD ESI, 0xE
- 00DE79D3 . 8BD0 MOV EDX, EAX ; GetProcAddress API调用已找到
- 00DE79D5 . 6A 02 PUSH 0x2 ; 2次调用子函数去
- 00DE79D7 . 59 POP ECX
- 00DE79D8 . E8 23FFFFFF CALL Portable.00DE7900 ; 去获取CopyFileW和LoadLibraryA
- 00DE79DD . 83C6 0D ADD ESI, 0xD
- 00DE79E0 . 52 PUSH EDX
- 00DE79E1 . 56 PUSH ESI
- 00DE79E2 . FF57 FC CALL NEAR DWORD PTR DS:[EDI-0x4] ; 用获取到的kernel32.LoadLibraryA去加载user32.dll获取其基地址
- 00DE79E5 . 5A POP EDX
- 00DE79E6 . 6A 01 PUSH 0x1 ; 1次调用
- 00DE79E8 . 59 POP ECX
- 00DE79E9 . 93 XCHG EAX, EBX ; 要换成user32.dll基地址用GetProcAddress去获取wsprintfW函数调用并存
- 00DE79EA . E8 11FFFFFF CALL Portable.00DE7900
- 00DE79EF . 61 POPAD ; 在此有关要调用的函数地址已全部取到了,恢复寄存器
- 00DE79F0 . E8 ACACF3FF CALL Portable.00D226A1 ; 执行原程序操作
- 00DE79F5 .^ E9 FFF5F2FF JMP Portable.00D16FF9
- /////////////////////////////////////////////////////////////////////////////////////////////
- 00DE79FA >- E9 B9590B00 JMP Portable.00E9D3B8 ; 下面的0000空间不能用了,跳到此中转还成,也为了方便看代码,去别的空隙吧
- 00DE79FF 00 DB 00
- 00DE7A00 00 DB 00
- 00DE7A01 00 DB 00
- 00DE7A02 00 DB 00
- 00DE7A03 00 DB 00
- 00DE7A04 00 DB 00
- 00DE7A05 00 DB 00
- 00DE7A06 00 DB 00
- 00DE7A07 00 DB 00
- 00DE7A08 00 DB 00
- 00DE7A09 00 DB 00
- 00DE7A0A 00 DB 00
- 00DE7A0B 00 DB 00
- 00DE7A0C 00 DB 00
复制代码 --------------------------------------------------------------------------------------------
第二处Patch
- 00402DD3 . E8 487C0000 CALL Portable.0040AA20
- 00402DD8 C645 FC 28 MOV BYTE PTR SS:[EBP-0x4], 0x28--------------> ; JMP 00DE79FA 此处发现程序已生面缓存地址可去利用
- 00402DDC C645 FC 26 MOV BYTE PTR SS:[EBP-0x4], 0x26
- 00402DE0 . 8B8D 70FFFFFF MOV ECX, DWORD PTR SS:[EBP-0x90]
复制代码 --------------------------------------字串存放处----------------------------------------------
- 00E9D357 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D359 49 DEC ECX
- 00E9D35A 003A ADD BYTE PTR DS:[EDX], BH
- 00E9D35C 002F ADD BYTE PTR DS:[EDI], CH
- 00E9D35E 0072 00 ADD BYTE PTR DS:[EDX], DH
- 00E9D361 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D362 0062 00 ADD BYTE PTR DS:[EDX], AH
- 00E9D365 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D366 0066 00 ADD BYTE PTR DS:[ESI], AH
- 00E9D369 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D36A 0072 00 ADD BYTE PTR DS:[EDX], DH
- 00E9D36D 6D INS DWORD PTR ES:[EDI], DX
- 00E9D36E 002E ADD BYTE PTR DS:[ESI], CH
- 00E9D370 006400 6C ADD BYTE PTR DS:[EAX+EAX+0x6C], AH
- 00E9D374 006C00 00 ADD BYTE PTR DS:[EAX+EAX], CH
- 00E9D378 0049 00 ADD BYTE PTR DS:[ECX], CL
- 00E9D37B 3A00 CMP AL, BYTE PTR DS:[EAX]
- 00E9D37D 2F DAS
- 00E9D37E 0072 00 ADD BYTE PTR DS:[EDX], DH
- 00E9D381 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D382 0062 00 ADD BYTE PTR DS:[EDX], AH
- 00E9D385 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D386 0066 00 ADD BYTE PTR DS:[ESI], AH
- 00E9D389 6F OUTS DX, DWORD PTR ES:[EDI]
- 00E9D38A 0072 00 ADD BYTE PTR DS:[EDX], DH
- 00E9D38D 6D INS DWORD PTR ES:[EDI], DX
- 00E9D38E 002D 00780036 ADD BYTE PTR DS:[0x36007800], CH
- 00E9D394 003400 ADD BYTE PTR DS:[EAX+EAX], DH
- 00E9D397 2E:006400 6C ADD BYTE PTR CS:[EAX+EAX+0x6C], AH
- 00E9D39C 006C00 00 ADD BYTE PTR DS:[EAX+EAX], CH
- 00E9D3A0 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D3A2 0025 0073002F ADD BYTE PTR DS:[0x2F007300], AH
- 00E9D3A8 0025 00730000 ADD BYTE PTR DS:[0x7300], AH
- 00E9D3AE 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D3B0 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D3B2 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D3B4 0000 ADD BYTE PTR DS:[EAX], AL
- 00E9D3B6 0000 ADD BYTE PTR DS:[EAX], AL
复制代码 -------------------------代码乱写没优化--------------------------------------------------------------------------
- 00E9D3B8 60 PUSHAD ; 保存一下寄存器
- 00E9D3B9 FC CLD
- 00E9D3BA 33D2 XOR EDX, EDX ; 本来想调用API的,但更本就没必要
- 00E9D3BC 64:8B15 3000000>MOV EDX, DWORD PTR FS:[0x30] ; 从PEB X30处开始找到程序运行所在要用的盘符
- 00E9D3C3 8B52 0C MOV EDX, DWORD PTR DS:[EDX+0xC]
- 00E9D3C6 8B52 14 MOV EDX, DWORD PTR DS:[EDX+0x14]
- 00E9D3C9 8B72 28 MOV ESI, DWORD PTR DS:[EDX+0x28]
- 00E9D3CC 83EE 06 SUB ESI, 0x6 ; 加6处就是
- 00E9D3CF E8 00000000 CALL Portable.00E9D3D4 ; 重定位地址
- 00E9D3D4 58 POP EAX
- 00E9D3D5 83E8 7B SUB EAX, 0x7B ; 本地址开始加上7B就是EAX 00E9D359 UNICODE "C:/roboform.dll"
- 00E9D3D8 8B0E MOV ECX, DWORD PTR DS:[ESI] ; 新盘符存到ECX
- 00E9D3DA 8908 MOV DWORD PTR DS:[EAX], ECX ; U码,4个字节刚好SMC写入
- 00E9D3DC 50 PUSH EAX ; 存到堆栈备用
- 00E9D3DD 83C0 06 ADD EAX, 0x6 ; 减6是roboform.dll字符串
- 00E9D3E0 50 PUSH EAX ; 存到堆栈备用
- 00E9D3E1 83C0 1A ADD EAX, 0x1A ; 减1A是EAX 00E9D379 UNICODE "C:/roboform-x64.dll"
- 00E9D3E4 8908 MOV DWORD PTR DS:[EAX], ECX ; U码,4个字节刚好SMC写入
- 00E9D3E6 50 PUSH EAX ; 存到堆栈备用
- 00E9D3E7 83C0 06 ADD EAX, 0x6 ; 减6是roboform-x64.dll字符串
- 00E9D3EA 50 PUSH EAX ; 存到堆栈备用
- 00E9D3EB 3E:FF7424 24 PUSH DWORD PTR DS:[ESP+0x24] ; 缓存地址压在栈头 UNICODE "C:/Users/qyc/AppData/Local/Temp/RoboForm"
- 00E9D3F0 5E POP ESI ; 弹到ESI
- 00E9D3F1 56 PUSH ESI ; 还是存一份在堆备用吧
- 00E9D3F2 83C0 24 ADD EAX, 0x24 ; 减24,就是UNICODE "%s/%s",这个是连接字符串要用的
- 00E9D3F5 50 PUSH EAX ; 也要存到堆栈备用
- 00E9D3F6 - E9 56A5F4FF JMP Portable.00DE7951 ; 我操,要JMP去存放API的地址调用取得,都怪空隙不足,要JMP,J来M去的
- 00E9D3FB 3E:FF7424 14 PUSH DWORD PTR DS:[ESP+0x14] ; 开始准备合体,第一个字串入栈堆栈 UNICODE "roboform.dll"
- 00E9D400 56 PUSH ESI ; ESI还有缓存地址,直接入。。。UNICODE "C:/Users/qyc/AppData/Local/Temp/RoboForm"
- 00E9D401 FF7424 0C PUSH DWORD PTR SS:[ESP+0xC] ; 第三个连接符。。。入堆栈 UNICODE "%s/%s"
- 00E9D405 81C6 50010000 ADD ESI, 0x150 ; 我发现缓存地址150的地方有一大遍000可用,但8.1下就不是OOO,但破坏后没事,就入吧
- 00E9D40B 56 PUSH ESI ; 压入
- 00E9D40C FF50 08 CALL NEAR DWORD PTR DS:[EAX+0x8] ; 调用 (user32.wsprintfW)合体
- 00E9D40F 6A 00 PUSH 0x0 ; 压入O,可。。。你知道的
- 00E9D411 56 PUSH ESI ; NEW新地址
- 00E9D412 FF7424 30 PUSH DWORD PTR SS:[ESP+0x30] ; 程序下破解好的DLL地址
- 00E9D416 8B4C24 1C MOV ECX, DWORD PTR SS:[ESP+0x1C]
- 00E9D41A FF11 CALL NEAR DWORD PTR DS:[ECX] ; 完成复制一个
- 00E9D41C FF7424 1C PUSH DWORD PTR SS:[ESP+0x1C]
- 00E9D420 FF7424 0C PUSH DWORD PTR SS:[ESP+0xC]
- 00E9D424 FF7424 0C PUSH DWORD PTR SS:[ESP+0xC]
- 00E9D428 56 PUSH ESI
- 00E9D429 FF7424 20 PUSH DWORD PTR SS:[ESP+0x20]
- 00E9D42D 5B POP EBX
- 00E9D42E FF53 08 CALL NEAR DWORD PTR DS:[EBX+0x8] ; 合成64位地址
- 00E9D431 6A 00 PUSH 0x0
- 00E9D433 56 PUSH ESI
- 00E9D434 FF7424 38 PUSH DWORD PTR SS:[ESP+0x38]
- 00E9D438 FF13 CALL NEAR DWORD PTR DS:[EBX] ; 完成复制动作
- 00E9D43A 61 POPAD ; 以下动作恢复堆栈弹掉没用的
- 00E9D43B 58 POP EAX
- 00E9D43C 58 POP EAX
- 00E9D43D 58 POP EAX
- 00E9D43E 58 POP EAX
- 00E9D43F 58 POP EAX
- 00E9D440 58 POP EAX
- 00E9D441 58 POP EAX
- 00E9D442 61 POPAD ; 还原寄存器
- 00E9D443 C645 FC 28 MOV BYTE PTR SS:[EBP-0x4], 0x28 ; 原程序动作
- 00E9D447 C645 FC 26 MOV BYTE PTR SS:[EBP-0x4], 0x26
- 00E9D44B - E9 9059D7FF JMP Portable.00C12DE0 ; 回去执行
- 00E9D450 90 NOP
复制代码 --------------------------------------------------------------------------------
【版权声明】: 本文原创于PYG论坛, 转载请注明作者并保持文章的完整, 谢谢!
2014年03月08日 20:35:04
|
评分
-
查看全部评分
|