首页
社区
课程
招聘
[原创]PEdiy RoboForm2Go 密码管理软件
发表于: 2014-3-9 09:09 5126

[原创]PEdiy RoboForm2Go 密码管理软件

qyc 活跃值
4
2014-3-9 09:09
5126

【文章标题】: PEdiy RoboForm2Go 密码管理软件
【文章作者】: 小Q
【作者邮箱】: qyc5@yahoo.com.cn
【作者主页】: 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
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2014年03月09日 9:06:52


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (1)
雪    币: 13201
活跃值: (4261)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这东东的确很好用的
不过还没完全搞懂怎么用。。
2014-3-9 09:22
0
游客
登录 | 注册 方可回帖
返回
//