这是原帖网址:http://bbs.pediy.com/showthread.php?t=128926
之前一直都是用C32Asm这个工具做一些小量的HEX修改的。前两天发现这个工具竟然有更新,就下载了pll621前辈的C32Asm。用了一下子,发现修改后不能备份原来的文件,我已经报告了BUG了,最后不耐烦还是自己动手,丰衣足食。(怀疑是不是pll621前辈特意留个BUG给我们发掘)
通过bp MessageBoxA 断点,掉过一大堆封装代码后来到如下代码:
00457FAE . 53 PUSH EBX
00457FAF . 6A 04 PUSH 4
00457FB1 . 52 PUSH EDX
00457FB2 . E8 33390900 CALL <JMP.&MFC42.#1200_?AfxMessageBox@@YGHPBDII@Z>; //提示是否保存
00457FB7 . 83F8 07 CMP EAX,7
00457FBA . 75 04 JNZ SHORT C32Asm.00457FC0 ; //如果选择保持的,就跳
00457FBC . 895C24 38 MOV DWORD PTR SS:[ESP+38],EBX ; //用一个变量SaveFlag标记是否保存,并且初始化为TRUE。如果不保存则,SaveFlag=FALSE
00457FC0 > 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10]
00457FC4 . C68424 7C0100>MOV BYTE PTR SS:[ESP+17C],6
00457FCC . E8 FB350900 CALL <JMP.&MFC42.#800_??1CString@@QAE@XZ>
对SaveFlag变量下数据访问断点,即00457FBC . 895C24 38 MOV DWORD PTR
SS:[ESP+38],EBX 这里的ESP+38这个地址。看哪里对它访问。可来到如下地方:
0045804B . 8B5424 38 MOV EDX,DWORD PTR SS:[ESP+38] ; //取已保存保存次数
0045804F . 51 PUSH ECX
00458050 . 8B88 78070000 MOV ECX,DWORD PTR DS:[EAX+778]
00458056 . 52 PUSH EDX ; //传递保存标记参数 ,SaveFlag
00458057 . 51 PUSH ECX
00458058 . E8 73FC0700 CALL C32Asm.004D7CD0 ; //这里就是进行保存操作的函数
0045805D > 8B8C24 740100>MOV ECX,DWORD PTR SS:[ESP+174]
00458064 . 5F POP EDI
对压入的SaveFlag参数下访问断点可到如下地方:
004D6C24 |. 8B8424 300100>MOV EAX,DWORD PTR SS:[ESP+130] ; //取SaveFlag,
004D6C2B |. 85C0 TEST EAX,EAX ; //这里判断是否保存文件
004D6C2D |. 0F84 D2000000 JE C32Asm.004D6D05 ; //不保存就跳走
004D6C33 |. 8A15 A00A6500 MOV DL,BYTE PTR DS:[650AA0]
004D6C39 |. B9 40000000 MOV ECX,40
004D6C3E |. 33C0 XOR EAX,EAX
004D6C40 |. 8D7C24 25 LEA EDI,DWORD PTR SS:[ESP+25]
004D6C44 |. 885424 24 MOV BYTE PTR SS:[ESP+24],DL
004D6C48 |. 8D9D D4430000 LEA EBX,DWORD PTR SS:[EBP+43D4]
004D6C4E |. F3:AB REP STOS DWORD PTR ES:[EDI]
004D6C50 |. 66:AB STOS WORD PTR ES:[EDI]
004D6C52 |. 8D5424 24 LEA EDX,DWORD PTR SS:[ESP+24]
004D6C56 |. AA STOS BYTE PTR ES:[EDI]
004D6C57 |. 8BC3 MOV EAX,EBX
004D6C59 |. 2BD3 SUB EDX,EBX
004D6C5B |> 8A08 /MOV CL,BYTE PTR DS:[EAX]
004D6C5D |. 880C02 |MOV BYTE PTR DS:[EDX+EAX],CL
004D6C60 |. 40 |INC EAX
004D6C61 |. 84C9 |TEST CL,CL
004D6C63 |.^ 75 F6 \JNZ SHORT C32Asm.004D6C5B
004D6C65 |. 8B8424 340100>MOV EAX,DWORD PTR SS:[ESP+134]
004D6C6C |. 83F8 64 CMP EAX,64
004D6C6F |. 7D 6C JGE SHORT C32Asm.004D6CDD
004D6C71 |. 85C0 TEST EAX,EAX
004D6C73 |. 7C 68 JL SHORT C32Asm.004D6CDD
004D6C75 |. 8A0D A00A6500 MOV CL,BYTE PTR DS:[650AA0]
004D6C7B |. 50 PUSH EAX ; /<%02d>
004D6C7C |. 8D5424 1C LEA EDX,DWORD PTR SS:[ESP+1C] ; |
004D6C80 |. 68 F0EC6400 PUSH C32Asm.0064ECF0 ; |format = ".b%02d"
004D6C85 |. 52 PUSH EDX ; |s
004D6C86 |. 884C24 24 MOV BYTE PTR SS:[ESP+24],CL ; |
004D6C8A |. C74424 25 000>MOV DWORD PTR SS:[ESP+25],0 ; |
004D6C92 |. FF15 84F35D00 CALL DWORD PTR DS:[<&MSVCRT.sprintf>] ; \//这里合成后缀名字符串
004D6C98 |. 8D7C24 24 LEA EDI,DWORD PTR SS:[ESP+24]
004D6C9C |. 83C9 FF OR ECX,FFFFFFFF
004D6C9F |. 33C0 XOR EAX,EAX
004D6CA1 |. 83C4 0C ADD ESP,0C
004D6CA4 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004D6CA6 |. F7D1 NOT ECX ; //后缀名长度,+ 结束字符NULL
004D6CA8 |. 2BF9 SUB EDI,ECX
004D6CAA |. 8D5424 24 LEA EDX,DWORD PTR SS:[ESP+24]
004D6CAE |. 8BF7 MOV ESI,EDI
004D6CB0 |. 8BC1 MOV EAX,ECX
004D6CB2 |. 8BFA MOV EDI,EDX
004D6CB4 |. 8BD0 MOV EDX,EAX
[COLOR="Red"]004D6CB6 897C24 18 MOV DWORD PTR SS:[ESP+18],EDI[/COLOR] ; [COLOR="Red"] //--------这里是BUG的所在,是保存程序路径字符串的指针到一个局部变量的。
//但是这里将指针保存到后缀字符窜所在的缓冲区,覆盖了备
//份文件路径后缀名的内容,最后拼接的路径不合法,导致了
//CopyFile调用失败,应该用另一个变量存放该指针[/COLOR]
004D6CBA |. 83C9 FF OR ECX,FFFFFFFF
004D6CBD |. 33C0 XOR EAX,EAX
004D6CBF |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; //将程序路径字符串指針移向字符串的结尾
004D6CC1 |. 8BCA MOV ECX,EDX
004D6CC3 |. 4F DEC EDI
004D6CC4 |. C1E9 02 SHR ECX,2
004D6CC7 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; //字符串的拼接
004D6CC9 |. 8BCA MOV ECX,EDX
[COLOR="Red"]004D6CCB 8B5424 18 MOV EDX,DWORD PTR SS:[ESP+18] ; //--------取程序路径字符串的指针,这个指针与上面的指针对应[/COLOR]
004D6CCF |. 83E1 03 AND ECX,3
004D6CD2 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; //拷贝结束字符NULL
004D6CD4 |. 8BB424 2C0100>MOV ESI,DWORD PTR SS:[ESP+12C]
004D6CDB |. EB 1E JMP SHORT C32Asm.004D6CFB ; //这里就跳到CopyFile,就是进行备份文件
通过对堆栈的局部变量所在的地址下断可以知道有几处地方可以利用,我就选择了[esp+20]这一处空间,修改上面两句代码用到的局部变量地址即可:
[COLOR="Red"]004D6CB6 897C24 20 MOV DWORD PTR SS:[ESP+20],EDI[/COLOR] ; //--------这里是BUG的所在,是保存程序路径字符串的指针。覆盖了后缀字符窜的內容,应该用另一个变量存放
004D6CBA |. 83C9 FF OR ECX,FFFFFFFF
004D6CBD |. 33C0 XOR EAX,EAX
004D6CBF |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; //将程序路径字符串指針移向字符串的结尾
004D6CC1 |. 8BCA MOV ECX,EDX
004D6CC3 |. 4F DEC EDI
004D6CC4 |. C1E9 02 SHR ECX,2
004D6CC7 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; //字符串的拼接
004D6CC9 |. 8BCA MOV ECX,EDX
[COLOR="Red"]004D6CCB 8B5424 20 MOV EDX,DWORD PTR SS:[ESP+20][/COLOR] ; //--------取程序路径字符串的指针,这个指针与上面的指针对应
如果错误之处,还请指正~~~
[课程]Android-CTF解题方法汇总!