0080606E 50 PUSH EAX
0080606F 8B8D 60EBFFFF MOV ECX, DWORD PTR SS:[EBP-14A0]
00806075 FF148D 0C888300 CALL DWORD PTR DS:[ECX*4+83880C]
//模拟模拟处理EFLAGS寄存器值来判断标志寄存器的标志位的函数入口
0080607C 83C4 0C ADD ESP, 0C
0080607F 8985 68EBFFFF MOV DWORD PTR SS:[EBP-1498], EAX
00806085 8B95 68EBFFFF MOV EDX, DWORD PTR SS:[EBP-1498] //取标志
0080608B 83E2 01 AND EDX, 1
0080608E 85D2 TEST EDX, EDX
00806090 0F84 AE000000 JE ezcddax.00806144 //判断是否需要跳转
在 00806075 FF148D 0C888300 CALL DWORD PTR DS:[ECX*4+83880C] 下断点,这个就是手工修复的麻烦所在,要每次跟踪看看。
正是这种方法没有技术,所以一直觉得没必要写出来,怕误人。
中断在上面的地址处,看看函数的入口是:
00806075 FF148D 0C888300 CALL DWORD PTR DS:[ECX*4+83880C] ; ezcddax.007FCAE9
DS:[00838BBC]=007FCAE9 (ezcddax.007FCAE9)
F7进入,看看这个处理过程:
007FCAE9 55 PUSH EBP
007FCAEA 8BEC MOV EBP, ESP
007FCAEC 83EC 40 SUB ESP, 40
007FCAEF C745 D0 6400000>MOV DWORD PTR SS:[EBP-30], 64
007FCAF6 C745 D4 5900000>MOV DWORD PTR SS:[EBP-2C], 59
007FCAFD C745 D8 8400000>MOV DWORD PTR SS:[EBP-28], 84
007FCB04 C745 DC 9C00000>MOV DWORD PTR SS:[EBP-24], 9C
007FCB0B C745 E0 C500000>MOV DWORD PTR SS:[EBP-20], 0C5
007FCB12 C745 E4 7800000>MOV DWORD PTR SS:[EBP-1C], 78
007FCB19 C745 E8 9D00000>MOV DWORD PTR SS:[EBP-18], 9D
007FCB20 C745 EC 4700000>MOV DWORD PTR SS:[EBP-14], 47
007FCB27 C745 F0 0400000>MOV DWORD PTR SS:[EBP-10], 4
007FCB2E C745 C0 0700000>MOV DWORD PTR SS:[EBP-40], 7
007FCB35 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8]
007FCB38 C1E8 04 SHR EAX, 4
007FCB3B 83E0 07 AND EAX, 7
007FCB3E 8B4C85 D0 MOV ECX, DWORD PTR SS:[EBP+EAX*4-30]
007FCB42 894D C4 MOV DWORD PTR SS:[EBP-3C], ECX
007FCB45 8B45 C4 MOV EAX, DWORD PTR SS:[EBP-3C]
007FCB48 99 CDQ
007FCB49 B9 19000000 MOV ECX, 19
007FCB4E F7F9 IDIV ECX
007FCB50 8945 CC MOV DWORD PTR SS:[EBP-34], EAX
007FCB53 8B45 C4 MOV EAX, DWORD PTR SS:[EBP-3C]
007FCB56 99 CDQ
007FCB57 B9 19000000 MOV ECX, 19
007FCB5C F7F9 IDIV ECX
007FCB5E 8955 C8 MOV DWORD PTR SS:[EBP-38], EDX
007FCB61 8B55 CC MOV EDX, DWORD PTR SS:[EBP-34]
007FCB64 3B55 C8 CMP EDX, DWORD PTR SS:[EBP-38]
007FCB67 75 11 JNZ SHORT ezcddax.007FCB7A
007FCB69 8B45 C8 MOV EAX, DWORD PTR SS:[EBP-38]
007FCB6C 83C0 01 ADD EAX, 1
007FCB6F 99 CDQ
007FCB70 B9 19000000 MOV ECX, 19
007FCB75 F7F9 IDIV ECX
007FCB77 8955 C8 MOV DWORD PTR SS:[EBP-38], EDX
007FCB7A 8B55 C4 MOV EDX, DWORD PTR SS:[EBP-3C]
007FCB7D 8B45 CC MOV EAX, DWORD PTR SS:[EBP-34]
007FCB80 8B0C95 48E48300 MOV ECX, DWORD PTR DS:[EDX*4+83E448]
007FCB87 330C85 CC828300 XOR ECX, DWORD PTR DS:[EAX*4+8382CC]
007FCB8E 8B55 C8 MOV EDX, DWORD PTR SS:[EBP-38]
007FCB91 330C95 CC828300 XOR ECX, DWORD PTR DS:[EDX*4+8382CC]
007FCB98 894D F8 MOV DWORD PTR SS:[EBP-8], ECX
007FCB9B 8B45 0C MOV EAX, DWORD PTR SS:[EBP+C]
007FCB9E 50 PUSH EAX
007FCB9F 8B4D C4 MOV ECX, DWORD PTR SS:[EBP-3C]
007FCBA2 0FBE91 88CC8300 MOVSX EDX, BYTE PTR DS:[ECX+83CC88]
007FCBA9 FF1495 C0CB8300 CALL DWORD PTR DS:[EDX*4+83CBC0]
007FCBB0 83C4 04 ADD ESP, 4
007FCBB3 8945 FC MOV DWORD PTR SS:[EBP-4], EAX
007FCBB6 8B45 10 MOV EAX, DWORD PTR SS:[EBP+10]
007FCBB9 50 PUSH EAX
007FCBBA 8B4D FC MOV ECX, DWORD PTR SS:[EBP-4]
007FCBBD 51 PUSH ECX
007FCBBE FF55 F8 CALL DWORD PTR SS:[EBP-8]
//真正的模拟处理EFLAGS寄存器值来判断标志寄存器的标志位的函数入口
007FCBC1 83C4 08 ADD ESP, 8
007FCBC4 50 PUSH EAX
007FCBC5 8B55 C4 MOV EDX, DWORD PTR SS:[EBP-3C]
007FCBC8 0FBE82 88CC8300 MOVSX EAX, BYTE PTR DS:[EDX+83CC88]
007FCBCF FF1485 24CC8300 CALL DWORD PTR DS:[EAX*4+83CC24]
007FCBD6 83C4 04 ADD ESP, 4
007FCBD9 8945 F4 MOV DWORD PTR SS:[EBP-C], EAX
007FCBDC 8B45 F4 MOV EAX, DWORD PTR SS:[EBP-C]
007FCBDF 83E0 01 AND EAX, 1
007FCBE2 8BE5 MOV ESP, EBP
007FCBE4 5D POP EBP
007FCBE5 C3 RETN
F7进入 007FCBBE (模拟处理EFLAGS寄存器值来判断标志寄存器的标志位的函数 )
分析这个函数:
007E8FE9 55 PUSH EBP
007E8FEA 8BEC MOV EBP, ESP
007E8FEC 83EC 0C SUB ESP, 0C
007E8FEF 53 PUSH EBX
007E8FF0 56 PUSH ESI
007E8FF1 57 PUSH EDI
007E8FF2 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8]
007E8FF5 50 PUSH EAX
007E8FF6 FF15 5CCC8300 CALL DWORD PTR DS:[83CC5C] ; ezcddax.007DDF8E
007E8FFC 83C4 04 ADD ESP, 4
007E8FFF 8945 FC MOV DWORD PTR SS:[EBP-4], EAX
007E9002 8B45 FC MOV EAX, DWORD PTR SS:[EBP-4]
//取域中EFLAGS寄存器值
堆栈 SS:[0012DC30]=00000246 <--CC发生时EFLAGS寄存器值
EAX=00000246
007E9005 70 07 JO SHORT ezcddax.007E900E
007E9007 7C 03 JL SHORT ezcddax.007E900C
007E9009 EB 05 JMP SHORT ezcddax.007E9010
007E900B - E9 74FBEBF9 JMP FA6A8B84
007E9010 53 PUSH EBX
007E9011 8B5D 0C MOV EBX, DWORD PTR SS:[EBP+C]
007E9014 BB FFFF0000 MOV EBX, 0FFFF
007E9019 23C3 AND EAX, EBX
//取后面2个字节,注意对EAX的处理
007E901B 51 PUSH ECX
007E901C B5 2C MOV CH, 2C
007E901E 80ED 01 SUB CH, 1
007E9021 80ED 20 SUB CH, 20
007E9024 FECD DEC CH
007E9026 FECD DEC CH
007E9028 80ED 04 SUB CH, 4
007E902B FECD DEC CH
007E902D 80ED 03 SUB CH, 3
007E9030 FECD DEC CH
007E9032 22E5 AND AH, CH
007E9034 B1 70 MOV CL, 70
007E9036 80E9 02 SUB CL, 2
007E9039 FEC9 DEC CL
007E903B FEC9 DEC CL
007E903D FEC9 DEC CL
007E903F 80E9 06 SUB CL, 6
007E9042 F6D0 NOT AL
007E9044 0FC9 BSWAP ECX
007E9046 F6D0 NOT AL
007E9048 83E0 00 AND EAX, 0 //EAX and 0 *
007E904B 0FC9 BSWAP ECX
007E904D FEC9 DEC CL
007E904F FEC9 DEC CL
007E9051 80E9 12 SUB CL, 12
007E9054 80C1 0B ADD CL, 0B
007E9057 FEC9 DEC CL
007E9059 FEC9 DEC CL
007E905B 70 07 JO SHORT ezcddax.007E9064
007E905D 7C 03 JL SHORT ezcddax.007E9062
007E905F EB 05 JMP SHORT ezcddax.007E9066
007E9061 C7 ???
007E9062 ^ 74 FB JE SHORT ezcddax.007E905F
007E9064 ^ EB F9 JMP SHORT ezcddax.007E905F
007E9066 FEC9 DEC CL
007E9068 FEC9 DEC CL
007E906A FEC9 DEC CL
007E906C FEC9 DEC CL
007E906E 80E9 40 SUB CL, 40
007E9071 80E9 01 SUB CL, 1
007E9074 FEC9 DEC CL
007E9076 FEC9 DEC CL
007E9078 FEC9 DEC CL
007E907A FEC9 DEC CL
007E907C FEC9 DEC CL
007E907E FEC9 DEC CL
007E9080 FEC9 DEC CL
007E9082 40 INC EAX // EAX +1 **
007E9083 FEC9 DEC CL
007E9085 F7D1 NOT ECX
007E9087 0FC8 BSWAP EAX
007E9089 F7D1 NOT ECX
007E908B 0FC8 BSWAP EAX
007E908D FEC1 INC CL
007E908F 80C1 02 ADD CL, 2
007E9092 59 POP ECX
007E9093 5B POP EBX
007E9094 8945 F4 MOV DWORD PTR SS:[EBP-C], EAX
// 得到的答案EAX=1 ***
007E9097 8B0D CC838300 MOV ECX, DWORD PTR DS:[8383CC]
007E909D 330D D0838300 XOR ECX, DWORD PTR DS:[8383D0]
007E90A3 D1E1 SHL ECX, 1
007E90A5 894D F8 MOV DWORD PTR SS:[EBP-8], ECX
007E90A8 837D F4 00 CMP DWORD PTR SS:[EBP-C], 0
007E90AC 74 09 JE SHORT ezcddax.007E90B7 // 会跳吗?永远不
007E90AE 8B55 F8 MOV EDX, DWORD PTR SS:[EBP-8]
007E90B1 83CA 01 OR EDX, 1
007E90B4 8955 F8 MOV DWORD PTR SS:[EBP-8], EDX
007E90B7 8B45 F8 MOV EAX, DWORD PTR SS:[EBP-8]
007E90BA 50 PUSH EAX
007E90BB FF15 F8CB8300 CALL DWORD PTR DS:[83CBF8] ; ezcddax.007DDE09
007E90C1 83C4 04 ADD ESP, 4
007E90C4 5F POP EDI
007E90C5 5E POP ESI
007E90C6 5B POP EBX
007E90C7 8BE5 MOV ESP, EBP
007E90C9 5D POP EBP
007E90CA C3 RETN
继续到跳转时的计算偏移量的代码:
008060BB 61 POPAD
008060BC 8B85 48EEFFFF MOV EAX, DWORD PTR SS:[EBP-11B8]
008060C2 8B0C85 18F28300 MOV ECX, DWORD PTR DS:[EAX*4+83F218]
008060C9 8B85 74EBFFFF MOV EAX, DWORD PTR SS:[EBP-148C]
008060CF 33D2 XOR EDX, EDX
008060D1 BE 17000000 MOV ESI, 17
008060D6 F7F6 DIV ESI
008060D8 8B85 74EBFFFF MOV EAX, DWORD PTR SS:[EBP-148C]
008060DE 8B0C81 MOV ECX, DWORD PTR DS:[ECX+EAX*4]
008060E1 338C95 70EEFFFF XOR ECX, DWORD PTR SS:[EBP+EDX*4-1190]
; 计算偏移量
008060E8 8B95 34ECFFFF MOV EDX, DWORD PTR SS:[EBP-13CC]
;CC发生时的地址
008060EE 03D1 ADD EDX, ECX
ECX=00000004 计算偏移量
EDX=00439891 (ezcddax.00439891) CC发生时的地址
008060F0 8995 34ECFFFF MOV DWORD PTR SS:[EBP-13CC], EDX
如果不跳转就到计算jump代码长度:
0080614F 8B85 48EEFFFF MOV EAX, DWORD PTR SS:[EBP-11B8]
00806155 8B0C85 D0F38300 MOV ECX, DWORD PTR DS:[EAX*4+83F3D0]
0080615C 8B95 74EBFFFF MOV EDX, DWORD PTR SS:[EBP-148C]
00806162 33C0 XOR EAX, EAX
00806164 8A0411 MOV AL, BYTE PTR DS:[ECX+EDX]
///////////////////////////////////////////////////////////////
指向一张跳转代码长度表,这个表中数值是代码长度-1位(因为CC占了一位)
01E8DC70 01 05 01 01 04 01 01 01 01 01 01 05 05 01 01 01
01E8DC80 01 05 04 01 05 01 01 01 01 04 01 01 01 01 05 04
01E8DC90 01 05 05 01 01 01 01 01 01 01 01 01 01 05 01 01
01E8DCA0 01 01 01 05 05 01 01 05 01 01 01 01 01 05 01 04
01E8DCB0 01 01 05 05 04 01 01 01 05 01 05 01 01 05 05 01
01E8DCC0 01 01 01 01 05 01 04 BA 0D F0 AD BA 0D F0 AD BA ?瓠?瓠
01E8DCD0 AB AB AB AB AB AB AB AB 00 00 00 00 00 00 00 00 ........
分析一般程序的代码都知道,跳转的长度存在3种情况:
I 短距离jump 长度为2个字节
II 长距离jump 长度为6个字节
III 长距离jmp 长度为5个字节
根据这个表的长度就能知道是长短jump,因为长短不同的jump的二进制表示方法不同。
//////////////////////////////////////////////////////////////////
00806167 8B8D 34ECFFFF MOV ECX, DWORD PTR SS:[EBP-13CC]
0080616D 03C8 ADD ECX, EAX
0080616F 898D 34ECFFFF MOV DWORD PTR SS:[EBP-13CC], ECX
0080613A 61 POPAD
0080613B 9D POPFD
0080613C 66:92 XCHG AX, DX
0080613E 66:92 XCHG AX, DX
00806140 8BC0 MOV EAX, EAX
00806142 EB 75 JMP SHORT ezcddax.008061B9
重新传输参数,再次修复CC
008061B9 8305 108F8200 0>ADD DWORD PTR DS:[828F10], 4 ; 参数+1
008061C0 8B15 108F8200 MOV EDX, DWORD PTR DS:[828F10]
008061C6 8B12 MOV EDX, DWORD PTR DS:[EDX]
008061C8 8915 008F8200 MOV DWORD PTR DS:[828F00], EDX
008061CE 83FA 00 CMP EDX, 0
008061D1 ^ 74 E6 JE SHORT ezcddax.008061B9
; 如果出现00000000,表示这个地址不是CC
008061D3 83FA FF CMP EDX, -1
008061D6 74 08 JE SHORT ezcddax.008061E0
; 如果是ffffffff 表示修复结束。