UltraEdit-32 10.20版脫殼記

看雪資料發表於2004-04-29

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

相關文章