UltraEdit-32 10.20版使用了Armadillo壳的CC技术,但是没有用到远地址jmp和IAT表乱序排列。所以比较简单些。
1.得到程序的正确代码:
由于没有使用远地址jmp和iat表远地址存放技术,所以就可以直接LordPE的ArmDump插件dump下。
由于dump时程序运行过了,所以这时的临时data段有了垃圾数据,必须重新得到这个段的初始数据,不然运行就会出错
方法如下:
跟踪发现是data段00595000开始 长度5000的段有错误。根据这个线索
BP OpenMutexA
然后按正常的方法(不用说了吧)
完成双进程到单进程的转换后
bp VirtualProtect 后F9运行程序,中断后再按4次F9(只能四次)并且注意堆栈中的这个函数调用地址,因为第5次就到
了壳的子进程中了。Ctrl+F9返回再Ctrl+F9一次来到这里:
005FAE71 >ADD ESP,4 <--返回
005FAE74 >MOV DWORD PTR SS:[EBP-54],EAX
005FAE77 >CMP DWORD PTR SS:[EBP-54],0
005FAE7B >JNZ SHORT Uedit320.005FAE84
005FAE7D >XOR EAX,EAX
005FAE7F >JMP Uedit320.005FB03C
005FAE84 >PUSH 0
005FAE86 >PUSH 1
005FAE88 >MOV EDX,DWORD PTR DS:[62C4F8]
005FAE8E >PUSH EDX
005FAE8F >CALL DWORD PTR DS:[62C4FC] <--这里进入壳的子进程地址,F7进入
005FAE95 >TEST EAX,EAX
005FAE97 >JNZ SHORT Uedit320.005FAEAA
005FAE99 >MOV DWORD PTR DS:[62C504],5
005FAEA3 >XOR EAX,EAX
005FAEA5 >JMP Uedit320.005FB03C
进入后来到这里:
00DDAA1B >PUSH EBP
00DDAA1C >MOV EBP,ESP
00DDAA1E >PUSH EBX
00DDAA1F >MOV EBX,DWORD PTR SS:[EBP+8]
00DDAA22 >PUSH ESI
00DDAA23 >MOV ESI,DWORD PTR SS:[EBP+C]
00DDAA26 >PUSH EDI
00DDAA27 >MOV EDI,DWORD PTR SS:[EBP+10]
00DDAA2A >TEST ESI,ESI
00DDAA2C >JNZ SHORT 00DDAA37
00DDAA2E >CMP DWORD PTR DS:[DEA9F4],0
00DDAA35 >JMP SHORT 00DDAA5D
这里Ctrl+S打开搜索窗口输入:
PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH EBX
XOR EBX,EBX
(这是第一个anti的地方的特征代码)
来到这里:
00DD7D72 >PUSH EBP
00DD7D73 >MOV EBP,ESP
00DD7D75 >PUSH ECX
00DD7D76 >PUSH EBX
00DD7D77 >XOR EBX,EBX //特征代码
00DD7D79 >CMP BYTE PTR DS:[DE9075],BL
00DD7D7F >PUSH ESI
00DD7D80 >PUSH EDI
00DD7D81 >JNZ SHORT 00DD7D94
00DD7D83 >CMP BYTE PTR DS:[DE8CB1],BL
00DD7D89 >JNZ SHORT 00DD7D94
00DD7D8B >CALL 00DB72E9 <--第一个anti函数
00DD7D90 >TEST EAX,EAX <--函数返回值,必须修改为0
00DD7D92 >JNZ SHORT 00DD7D9B
00DD7D94 >XOR AL,AL
00DD7D96 >JMP 00DD7EC7
过了第一个anti后,bp VirtualAlloc 这时要仔细的看看堆栈中函数调用的地址,F9运行二次,Alt+F9返回
取消原来的断点后bp memcpy F9运行中断后检查堆栈中的第一个参数,如果变成了远地址(不是壳的子进程的地址)
如:0012BABC 01570020 |dest = 01570020 <--这个
就Alt+F9返回到壳的子进程中,Cltr+F9来到:
00DD34C8 >PUSH EAX
00DD34C9 >PUSH DWORD PTR SS:[EBP-1A1C]
00DD34CF >PUSH DWORD PTR DS:[DE9090] ; Uedit320.0066CCE6
00DD34D5 >CALL 00DB76C8
00DD34DA >ADD ESP,14 //返回地址,下面快到复制代码的地方了。
00DD34DD >MOV DWORD PTR DS:[DE9090],EAX
00DD34E2 >CMP DWORD PTR DS:[DE9090],0
00DD34E9 >JNZ SHORT 00DD350C
00DD34EB >MOV EAX,DWORD PTR SS:[EBP+8]
00DD34EE >MOV EAX,DWORD PTR DS:[EAX]
00DD34F0 >AND DWORD PTR DS:[EAX],0
00DD34F3 >PUSH 0DE1A38 ; ASCII "Location ES1"
00DD34F8 >MOV EAX,DWORD PTR SS:[EBP+8]
00DD34FB >PUSH DWORD PTR DS:[EAX+4]
00DD34FE >CALL 00DDA90C ; JMP to msvcrt.strcpy
向下看看:
00DD3692 >ADD EAX,DWORD PTR SS:[EBP-1A2C]
00DD3698 >MOV ECX,DWORD PTR SS:[EBP-1A48]
00DD369E >SUB ECX,EAX
00DD36A0 >MOV DWORD PTR SS:[EBP-1A4C],ECX
00DD36A6 >MOV EAX,DWORD PTR DS:[DE9560]
00DD36AB >MOV AL,BYTE PTR DS:[EAX+3D2F]
00DD36B1 >MOV BYTE PTR SS:[EBP-31AC],AL
00DD36B7 >MOVZX EAX,BYTE PTR SS:[EBP-31AC]
00DD36BE >TEST EAX,EAX
00DD36C0 >JE SHORT 00DD36DE
00DD36C2 >MOV EAX,DWORD PTR SS:[EBP-1A44]
00DD36C8 >XOR EAX,DWORD PTR SS:[EBP-1A3C]
00DD36CE >MOV ECX,DWORD PTR SS:[EBP-1A24]
00DD36D4 >ADD ECX,DWORD PTR SS:[EBP-1A4C]
00DD36DA >MOV DWORD PTR DS:[ECX],EAX
00DD36DC >JMP SHORT 00DD36F2 //*********
00DD36DE >MOV EAX,DWORD PTR SS:[EBP-1A24]
00DD36E4 >ADD EAX,DWORD PTR SS:[EBP-1A4C]
00DD36EA >MOV ECX,DWORD PTR SS:[EBP-1A44]
00DD36F0 >MOV DWORD PTR DS:[EAX],ECX
00DD36F2 >JMP SHORT 00DD3702 //***********
00DD36F4 >MOV EAX,DWORD PTR SS:[EBP-1A48]
00DD36FA >MOV ECX,DWORD PTR SS:[EBP-1A44]
00DD3700 >MOV DWORD PTR DS:[EAX],ECX
00DD3702 ^>JMP 00DD3611 //**********
00DD3707 >MOV EAX,DWORD PTR DS:[DE9560] //这三个jmp是特征代码
00DD370C >MOV AL,BYTE PTR DS:[EAX+3D2F]
00DD3712 >MOV BYTE PTR SS:[EBP-31B0],AL
00DD3718 >MOVZX EAX,BYTE PTR SS:[EBP-31B0] <--第二个anti的地方,修改下面的EAX值为0
00DD371F >TEST EAX,EAX
00DD3721 >JE 00DD3851
修改后再看看下面就是复制代码到程序中的段了:
00DD38B9 CALL DWORD PTR DS:[DDB138] ; kernel32.VirtualProtect //设置段的属性为可读写
00DD38BF PUSH DWORD PTR SS:[EBP-1A28]
00DD38C5 PUSH DWORD PTR SS:[EBP-1A24]
00DD38CB MOV EAX,DWORD PTR SS:[EBP-18E8]
00DD38D1 ADD EAX,DWORD PTR SS:[EBP-1A2C]
00DD38D7 PUSH EAX <--复制到的段基地址 //注意这里
00DD38D8 CALL 00DDA8B2 ; JMP to msvcrt.memcpy //复制函数
00DD38DD ADD ESP,0C
00DD38E0 LEA EAX,DWORD PTR SS:[EBP-1A30]
00DD38E6 PUSH EAX
00DD38E7 PUSH DWORD PTR SS:[EBP-1A30]
00DD38ED PUSH DWORD PTR SS:[EBP-1A28]
00DD38F3 MOV EAX,DWORD PTR SS:[EBP-18E8]
00DD38F9 ADD EAX,DWORD PTR SS:[EBP-1A2C]
00DD38FF PUSH EAX
00DD3900 CALL DWORD PTR DS:[DDB138] ; kernel32.VirtualProtect //重新设置段的属性为只读
00DD3906 MOV EAX,DWORD PTR SS:[EBP-1A24]
00DD390C MOV DWORD PTR SS:[EBP-2FF8],EAX
00DD3912 PUSH DWORD PTR SS:[EBP-2FF8]
00DD3918 CALL 00DDA8AC ; JMP to msvcrt.??3@YAXPAX@Z
00DD391D POP ECX
00DD391E JMP 00DD33C9
说明:如果是3.60版之前的可以在这里得到程序的代码,因为第一次复制的就是基地址为401000的程序代码段
但是3.61版后这个方法不行了,因为子进程的程序代码经过了xor后的代码,这个xor解码由父进程完成。但是对数据段
没有加密。所以可以在这里得到。
在00DD38D7 PUSH EAX 下断,跟踪直到基地址是00595000就可以在经过msvcrt.memcpy这个函数
后把这个段的代码用OD的二进制复制方法复制下来,然后再用OD打开LordPE原来dump的程序。把数据粘连到00595000段,这
就是个原始的data段了。
2.IAT表的处理
再向下运行,经过2个解码段
00DD4253 >ADD EAX,4
00DD4256 >MOV DWORD PTR SS:[EBP-1B44],EAX
00DD425C ^>JMP SHORT 00DD4228
00DD425E >XCHG EDX,EDI //解码完成的特征代码
00DD4260 >NOP
00DD4261 >XCHG EDX,EDI
00DD4263 >JPE SHORT 00DD4263
经过上面的解码后向下查找第三个anti的地方:
00DD452E >JNZ SHORT 00DD4541
00DD4530 >MOV EAX,DWORD PTR SS:[EBP-1D74]
00DD4536 >MOV EAX,DWORD PTR DS:[EAX+4]
00DD4539 >MOV DWORD PTR SS:[EBP-1B4C],EAX
00DD453F >JMP SHORT 00DD4546 //**********
00DD4541 ^>JMP 00DD4496 //*********
00DD4546 >AND BYTE PTR SS:[EBP-1B54],0 //第三个anti的特征代码
00DD454D >CMP DWORD PTR SS:[EBP-1910],0
00DD4554 >JNZ SHORT 00DD4595
00DD4556 >MOV EAX,DWORD PTR DS:[DE9560]
00DD455B >MOV AL,BYTE PTR DS:[EAX+3D2F]
00DD4561 >MOV BYTE PTR SS:[EBP-31B8],AL
00DD4567 >MOVZX EAX,BYTE PTR SS:[EBP-31B8] <--第三个anti,修改下面的EAX值为0
00DD456E >TEST EAX,EAX
00DD4570 >JE SHORT 00DD4595
过了第三个anti后就来到IAT解码的地方:
00DD467A CALL DWORD PTR DS:[DDB138] ; kernel32.VirtualProtect
00DD4680 PUSH 1
00DD4682 POP EAX
00DD4683 TEST EAX,EAX
00DD4685 JE 00DD494A
00DD468B AND WORD PTR SS:[EBP-1D7C],0
00DD4693 AND DWORD PTR SS:[EBP-1D84],0
00DD469A AND DWORD PTR SS:[EBP-1D80],0
00DD46A1 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD46A7 MOVSX EAX,BYTE PTR DS:[EAX]
00DD46AA TEST EAX,EAX
00DD46AC JNZ SHORT 00DD46F2
00DD46AE LEA ECX,DWORD PTR SS:[EBP-17C0]
00DD46B4 CALL 00DB1040
00DD46B9 MOVZX EAX,AL
00DD46BC CDQ
00DD46BD PUSH 14
00DD46BF POP ECX
00DD46C0 IDIV ECX
00DD46C2 MOV EAX,DWORD PTR SS:[EBP-17E4]
00DD46C8 MOV ECX,DWORD PTR SS:[EBP+EDX*4-1960] ; 修改为 XOR ECX,ECX
00DD46CF MOV DWORD PTR DS:[EAX],ECX
00DD46D1 MOV EAX,DWORD PTR SS:[EBP-17E4]
00DD46D7 ADD EAX,4
00DD46DA MOV DWORD PTR SS:[EBP-17E4],EAX
00DD46E0 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD46E6 INC EAX
00DD46E7 MOV DWORD PTR SS:[EBP-1780],EAX
00DD46ED JMP 00DD494A
00DD46F2 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD46F8 MOVZX EAX,BYTE PTR DS:[EAX]
00DD46FB CMP EAX,0FF
00DD4700 JNZ 00DD4790
00DD4706 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD470C INC EAX
00DD470D MOV DWORD PTR SS:[EBP-1780],EAX
00DD4713 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD4719 MOV AX,WORD PTR DS:[EAX]
00DD471C MOV WORD PTR SS:[EBP-1D7C],AX
00DD4723 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD4729 INC EAX
00DD472A INC EAX
00DD472B MOV DWORD PTR SS:[EBP-1780],EAX
00DD4731 CMP DWORD PTR SS:[EBP-1B4C],0
00DD4738 JE SHORT 00DD478B
00DD473A MOV EAX,DWORD PTR SS:[EBP-1B4C]
00DD4740 MOV DWORD PTR SS:[EBP-1D88],EAX
00DD4746 JMP SHORT 00DD4757
00DD4748 MOV EAX,DWORD PTR SS:[EBP-1D88]
00DD474E ADD EAX,0C
00DD4751 MOV DWORD PTR SS:[EBP-1D88],EAX
00DD4757 MOV EAX,DWORD PTR SS:[EBP-1D88]
00DD475D CMP DWORD PTR DS:[EAX+8],0
00DD4761 JE SHORT 00DD478B
00DD4763 MOVZX EAX,WORD PTR SS:[EBP-1D7C]
00DD476A MOV ECX,DWORD PTR SS:[EBP-1D88]
00DD4770 MOVZX ECX,WORD PTR DS:[ECX+4]
00DD4774 CMP EAX,ECX
00DD4776 JNZ SHORT 00DD4789
00DD4778 MOV EAX,DWORD PTR SS:[EBP-1D88]
00DD477E MOV EAX,DWORD PTR DS:[EAX+8]
00DD4781 MOV DWORD PTR SS:[EBP-1D80],EAX
00DD4787 JMP SHORT 00DD478B
00DD4789 JMP SHORT 00DD4748
00DD478B JMP 00DD482D
00DD4790 MOV EAX,DWORD PTR SS:[EBP-1780]
00DD4796 MOV DWORD PTR SS:[EBP-1D84],EAX
00DD479C PUSH 0
00DD479E PUSH DWORD PTR SS:[EBP-1780]
00DD47A4 CALL DWORD PTR DS:[DDB2C4] ; msvcrt.strchr
00DD47AA POP ECX
00DD47AB POP ECX
00DD47AC INC EAX
00DD47AD MOV DWORD PTR SS:[EBP-1780],EAX
00DD47B3 CMP DWORD PTR SS:[EBP-1B4C],0
00DD47BA JE SHORT 00DD482D
00DD47BC MOV EAX,DWORD PTR SS:[EBP-1B4C]
00DD47C2 MOV DWORD PTR SS:[EBP-1D8C],EAX
00DD47C8 JMP SHORT 00DD47D9
00DD47CA MOV EAX,DWORD PTR SS:[EBP-1D8C]
00DD47D0 ADD EAX,0C
00DD47D3 MOV DWORD PTR SS:[EBP-1D8C],EAX
00DD47D9 MOV EAX,DWORD PTR SS:[EBP-1D8C]
00DD47DF CMP DWORD PTR DS:[EAX+8],0
00DD47E3 JE SHORT 00DD482D
00DD47E5 PUSH 100
00DD47EA LEA EAX,DWORD PTR SS:[EBP-1E8C]
00DD47F0 PUSH EAX
00DD47F1 MOV EAX,DWORD PTR SS:[EBP-1D8C]
00DD47F7 PUSH DWORD PTR DS:[EAX]
00DD47F9 CALL 00DB7CF7
00DD47FE ADD ESP,0C
00DD4801 LEA EAX,DWORD PTR SS:[EBP-1E8C]
00DD4807 PUSH EAX
00DD4808 PUSH DWORD PTR SS:[EBP-1D84]
00DD480E CALL DWORD PTR DS:[DDB330] ; msvcrt._stricmp
00DD4814 POP ECX
00DD4815 POP ECX
00DD4816 TEST EAX,EAX
00DD4818 JNZ SHORT 00DD482B
00DD481A MOV EAX,DWORD PTR SS:[EBP-1D8C]
00DD4820 MOV EAX,DWORD PTR DS:[EAX+8]
00DD4823 MOV DWORD PTR SS:[EBP-1D80],EAX
00DD4829 JMP SHORT 00DD482D
00DD482B JMP SHORT 00DD47CA
00DD482D CMP DWORD PTR SS:[EBP-1D80],0
00DD4834 JNZ SHORT 00DD4875 // 这里NOP掉
00DD4836 MOVZX EAX,WORD PTR SS:[EBP-1D7C]
00DD483D TEST EAX,EAX
00DD483F JE SHORT 00DD4850
00DD4841 MOVZX EAX,WORD PTR SS:[EBP-1D7C]
00DD4848 MOV DWORD PTR SS:[EBP-323C],EAX
00DD484E JMP SHORT 00DD485C
00DD4850 MOV EAX,DWORD PTR SS:[EBP-1D84]
00DD4856 MOV DWORD PTR SS:[EBP-323C],EAX
00DD485C PUSH DWORD PTR SS:[EBP-323C]
00DD4862 PUSH DWORD PTR SS:[EBP-1B48]
00DD4868 CALL 00DB9C5C //这里修改为 call GetProcAddress
00DD486D POP ECX // 这里NOP掉
00DD486E POP ECX // 这里NOP掉
00DD486F MOV DWORD PTR SS:[EBP-1D80],EAX
00DD4875 CMP DWORD PTR SS:[EBP-1D80],0
00DD487C JNZ 00DD491A
00DD4882 MOVZX EAX,WORD PTR SS:[EBP-1D7C]
00DD4889 TEST EAX,EAX
00DD488B JE SHORT 00DD48E1
00DD488D CALL DWORD PTR DS:[DDB0D8] ; ntdll.RtlGetLastWin32Error
00DD4893 CMP EAX,32
00DD4896 JNZ SHORT 00DD48A4
00DD4898 MOV DWORD PTR SS:[EBP-1D80],0DB9C51
00DD48A2 JMP SHORT 00DD48DF
00DD48A4 MOV EAX,DWORD PTR SS:[EBP+8]
00DD48A7 MOV EAX,DWORD PTR DS:[EAX]
00DD48A9 MOV DWORD PTR DS:[EAX],3
00DD48AF CALL DWORD PTR DS:[DDB0D8] ; ntdll.RtlGetLastWin32Error
00DD48B5 PUSH EAX
00DD48B6 MOVZX EAX,WORD PTR SS:[EBP-1D7C]
00DD48BD PUSH EAX
00DD48BE PUSH DWORD PTR SS:[EBP-1C64]
00DD48C4 PUSH 0DE19D4 ; ASCII "File "%s", ordinal %d (error %d)"
00DD48C9 MOV EAX,DWORD PTR SS:[EBP+8]
00DD48CC PUSH DWORD PTR DS:[EAX+4]
00DD48CF CALL DWORD PTR DS:[DDB2C0] ; msvcrt.sprintf
00DD48D5 ADD ESP,14
00DD48D8 XOR EAX,EAX
00DD48DA JMP 00DD58C2
00DD48DF JMP SHORT 00DD491A
00DD48E1 MOV EAX,DWORD PTR SS:[EBP+8]
00DD48E4 MOV EAX,DWORD PTR DS:[EAX]
00DD48E6 MOV DWORD PTR DS:[EAX],3
00DD48EC CALL DWORD PTR DS:[DDB0D8] ; ntdll.RtlGetLastWin32Error
00DD48F2 PUSH EAX
00DD48F3 PUSH DWORD PTR SS:[EBP-1D84]
00DD48F9 PUSH DWORD PTR SS:[EBP-1C64]
00DD48FF PUSH 0DE19B0 ; ASCII "File "%s", function "%s" (error %d)"
00DD4904 MOV EAX,DWORD PTR SS:[EBP+8]
00DD4907 PUSH DWORD PTR DS:[EAX+4]
00DD490A CALL DWORD PTR DS:[DDB2C0] ; msvcrt.sprintf
00DD4910 ADD ESP,14
00DD4913 XOR EAX,EAX
00DD4915 JMP 00DD58C2
00DD491A MOV EAX,DWORD PTR SS:[EBP-17E4]
00DD4920 CMP EAX,DWORD PTR SS:[EBP-1798]
00DD4926 JNB SHORT 00DD4945
00DD4928 MOV EAX,DWORD PTR SS:[EBP-17E4]
00DD492E MOV ECX,DWORD PTR SS:[EBP-1D80]
00DD4934 MOV DWORD PTR DS:[EAX],ECX // 在此处设一次断以找到 iat的位置
00DD4936 MOV EAX,DWORD PTR SS:[EBP-17E4]
00DD493C ADD EAX,4
00DD493F MOV DWORD PTR SS:[EBP-17E4],EAX
00DD4945 JMP 00DD4680
以上是采用了jingulong的方法,十分的好用。
由于没有采用远地址IAT调用,所以到这里得到了完整的IAT表,用Import.Reconstructor得到完整的表。修复dump的程序就可以
正常运行了。
3.CC的修复
CC的修复比较麻烦,因为arm壳运行时并不需要具体的跳转类型,他只要确定是跳或者不跳 跳转的地址就能运行了。所以类型
不是十分的清晰。
再次用OD加载原主程序,he WaitForDebugEvent F9运行程序中断后取消这个断点,bp GetThreadContext F9运行中断后再运行一次
再次中断后Alt+F9返回到壳的子进程中,F8运行程序到这里:
006011F1 CALL Uedit320.005E9F90
006011F6 ADD ESP,0C
006011F9 MOV DWORD PTR SS:[EBP-1194],EAX
006011FF MOV EAX,DWORD PTR SS:[EBP-1194]
00601205 XOR EDX,EDX
00601207 MOV ECX,10
0060120C DIV ECX
0060120E MOV DWORD PTR SS:[EBP-1198],EDX
00601214 MOV EDX,DWORD PTR SS:[EBP-13AC] ; Uedit320.0040CD96
0060121A PUSH EDX //这里是程序的CC地址下面的首地址
0060121B MOV EAX,DWORD PTR SS:[EBP-1198] //跟踪这里就可以得到所有CC的地址了
00601221 CALL DWORD PTR DS:[EAX*4+62A838]
00601228 ADD ESP,4
0060122B MOV DWORD PTR SS:[EBP-1468],EAX
00601231 MOV DWORD PTR SS:[EBP-146C],0
0060123B MOV ECX,DWORD PTR SS:[EBP-1198]
00601241 MOV EDX,DWORD PTR DS:[ECX*4+62C6D4]
00601248 MOV DWORD PTR SS:[EBP-118C],EDX
0060124E MOV EAX,DWORD PTR SS:[EBP-146C]
00601254 CMP EAX,DWORD PTR SS:[EBP-118C]
0060125A JGE SHORT Uedit320.006012B8
0060125C MOV EAX,DWORD PTR SS:[EBP-118C]
00601262 SUB EAX,DWORD PTR SS:[EBP-146C]
00601268 CDQ
00601269 SUB EAX,EDX
0060126B SAR EAX,1
0060126D MOV ECX,DWORD PTR SS:[EBP-146C]
00601273 ADD ECX,EAX
00601275 MOV DWORD PTR SS:[EBP-1470],ECX
0060127B MOV EDX,DWORD PTR SS:[EBP-1198]
00601281 MOV EAX,DWORD PTR DS:[EDX*4+62C68C]
00601288 MOV ECX,DWORD PTR SS:[EBP-1470]
0060128E MOV EDX,DWORD PTR SS:[EBP-1468]
00601294 CMP EDX,DWORD PTR DS:[EAX+ECX*4]
00601297 JBE SHORT Uedit320.006012AA
00601299 MOV EAX,DWORD PTR SS:[EBP-1470]
0060129F ADD EAX,1
006012A2 MOV DWORD PTR SS:[EBP-146C],EAX
006012A8 JMP SHORT Uedit320.006012B6
006012AA MOV ECX,DWORD PTR SS:[EBP-1470]
006012B0 MOV DWORD PTR SS:[EBP-118C],ECX
006012B6 JMP SHORT Uedit320.0060124E //这个循环是对地址的计算,用于下面的判断
006012B8 PUSHAD
006012B9 XOR EAX,EAX
006012BB JNZ SHORT Uedit320.006012BF
006012BD JMP SHORT Uedit320.006012D4
继续向前:
00601357 >MOV EAX,DWORD PTR SS:[EBP-1198]
0060135D >MOV ECX,DWORD PTR DS:[EAX*4+62C714]
00601364 >MOV EDX,DWORD PTR SS:[EBP-146C]
0060136A >XOR EAX,EAX
0060136C >MOV AL,BYTE PTR DS:[ECX+EDX]
0060136F >MOV DWORD PTR SS:[EBP-1488],EAX
00601375 >MOV EAX,DWORD PTR SS:[EBP-1488]
0060137B >CDQ
0060137C >AND EDX,0F
0060137F >ADD EAX,EDX
00601381 >SAR EAX,4
00601384 >MOV DWORD PTR SS:[EBP-1480],EAX
0060138A >MOV ECX,DWORD PTR SS:[EBP-1488]
00601390 >AND ECX,8000000F
00601396 >JNS SHORT Uedit320.0060139D
00601398 >DEC ECX
00601399 >OR ECX,FFFFFFF0
0060139C >INC ECX
0060139D >MOV DWORD PTR SS:[EBP-1484],ECX
006013A3 >MOV EDX,DWORD PTR SS:[EBP-1480]
006013A9 >CMP EDX,DWORD PTR SS:[EBP-1484]
006013AF >JNZ SHORT Uedit320.006013CC
006013B1 >MOV EAX,DWORD PTR SS:[EBP-1484]
006013B7 >ADD EAX,1
006013BA >AND EAX,8000000F
006013BF >JNS SHORT Uedit320.006013C6
006013C1 >DEC EAX
006013C2 >OR EAX,FFFFFFF0
006013C5 >INC EAX
006013C6 >MOV DWORD PTR SS:[EBP-1484],EAX
006013CC >MOV ECX,DWORD PTR SS:[EBP-1488]
006013D2 >MOV EDX,DWORD PTR SS:[EBP-1480]
006013D8 >MOV EAX,DWORD PTR DS:[ECX*4+62BED0]
006013DF >XOR EAX,DWORD PTR DS:[EDX*4+62625C]
006013E6 >MOV ECX,DWORD PTR SS:[EBP-1484]
006013EC >XOR EAX,DWORD PTR DS:[ECX*4+62625C]
006013F3 >MOV DWORD PTR SS:[EBP-1478],EAX
006013F9 >MOV EDX,DWORD PTR SS:[EBP-13A4]
006013FF >AND EDX,0FD7
00601405 >PUSH EDX
00601406 >MOV EAX,DWORD PTR SS:[EBP-1488]
0060140C >MOVSX ECX,BYTE PTR DS:[EAX+62A730] //取第一个标志
00601413 >CALL DWORD PTR DS:[ECX*4+62A838] //根据标志计算
0060141A >ADD ESP,4
0060141D >MOV DWORD PTR SS:[EBP-1474],EAX
00601423 >MOV EDX,DWORD PTR SS:[EBP-13B8]
00601429 >PUSH EDX
0060142A >MOV EAX,DWORD PTR SS:[EBP-1474]
00601430 >PUSH EAX
00601431 >CALL DWORD PTR SS:[EBP-1478]
00601437 >ADD ESP,8
0060143A >PUSH EAX
0060143B >MOV ECX,DWORD PTR SS:[EBP-1488]
00601441 >MOVSX EDX,BYTE PTR DS:[ECX+62A730] //取第二个标志
00601448 >CALL DWORD PTR DS:[EDX*4+62A878] //根据标志计算
0060144F >ADD ESP,4
00601452 >MOV DWORD PTR SS:[EBP-147C],EAX //返回值用于跳与不跳的判断
00601458 >MOV EAX,DWORD PTR SS:[EBP-147C]
0060145E >AND EAX,1
00601461 >TEST EAX,EAX //判断上面计算的值,如果EAX=0
00601463 >JE Uedit320.00601517 //就不跳,否则就是跳转。
00601469 >PUSHAD
0060146A >XOR EAX,EAX
0060146C >JNZ SHORT Uedit320.00601470
0060146E >JMP SHORT Uedit320.00601485
如果上面的EAX值不是0 即必须跳转就来到下面计算跳转偏移的地方:
0060148E >POPAD
0060148F >MOV ECX,DWORD PTR SS:[EBP-1198]
00601495 >MOV ECX,DWORD PTR DS:[ECX*4+62C64C]
0060149C >MOV EAX,DWORD PTR SS:[EBP-146C]
006014A2 >XOR EDX,EDX
006014A4 >MOV ESI,10
006014A9 >DIV ESI
006014AB >MOV EAX,DWORD PTR SS:[EBP-146C]
006014B1 >MOV ECX,DWORD PTR DS:[ECX+EAX*4] //表1中的值
006014B4 >XOR ECX,DWORD PTR SS:[EBP+EDX*4-1170] //xor 表2中的值,得到的ECX就是偏移
006014BB >MOV EDX,DWORD PTR SS:[EBP-13AC] //CC地址下面的首地址
006014C1 >ADD EDX,ECX //相加就是要到达的地址
006014C3 >MOV DWORD PTR SS:[EBP-13AC],EDX //这个值就是子进程EIP的值
如果上面判断的值EAX=0 即不跳就来到这里:
00601522 MOV EAX,DWORD PTR SS:[EBP-1198]
00601528 MOV ECX,DWORD PTR DS:[EAX*4+62C758] //跳转代码长度-1表
0060152F MOV EDX,DWORD PTR SS:[EBP-146C] //取值的偏移
00601535 XOR EAX,EAX
00601537 MOV AL,BYTE PTR DS:[ECX+EDX] //根据上面的偏移取出跳转代码长度-1的值
0060153A MOV ECX,DWORD PTR SS:[EBP-13AC] //CC地址下面的首地址
00601540 ADD ECX,EAX //相加就是要到达的地址
00601542 MOV DWORD PTR SS:[EBP-13AC],ECX //这个值就是子进程EIP的值
跳转代码长度-1表:
00DB8070 01 04 01 05 01 04 01 01
00DB8078 01 04 01 05 01 01 05 01
00DB8080 01 05 05 04 05 01 01 05
00DB8088 01 01 01 01 01 05 01 01
00DB8090 05 01 01 01 01 05 01 01
00DB8098 01 01 01 01 04 05 01 01
00DB80A0 01 05 05 01 05 05 04 05
00DB80A8 01 05 01 01 01 05 01 01
00DB80B0 05 01 04 01 05 01 01 05
00DB80B8 05 01 01 04 05 01 01 04
00DB80C0 05 01 01 01 01 01 05 05
00DB80C8 01 01 01 01 04 01 05 01
00DB80D0 05 05 01 01 05 05 01 01
00DB80D8 01 05 01 05 01 01 01 01
00DB80E0 01 01 01 04 01 05 01 05
00DB80E8 01 05 01 05 05 04 01 05
00DB80F0 04 04 01 01 01 01 01 01
00DB80F8 01 05 01 01 05 05 01 04
00DB8100 05 01 04 05 01 05 05 04
00DB8108 01 01 05 01 01 01 01 01
00DB8110 01 01 01 01 01 05 01 05
00DB8118 04 05 01 01 01 01 05 01
00DB8120 05 05 05 01 01 05 05 05
00DB8128 05 01 01 05 01 01 05
跟踪上面的关键地方就能得到一个cc跳转表。根据这个表修改dump的程序。
当然你也可以修改子进程的跳转方向,即修改:
0060145E >AND EAX,1
00601461 >TEST EAX,EAX //判断上面计算的值,如果EAX=0
00601463 >JE Uedit320.00601517 //就不跳,否则就是跳转。
修改EAX的值就可以让程序按自己的需要跳转了:)
关于这篇脱文,这只是我个人的跟踪所得,未必正确。请不必当成教条!
我的知识也是来源于网上,所得也不敢独享,所以有文章。
fxyang
2004.4.28
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课