首页
社区
课程
招聘
[求助]?求翻诅呃篇SafeDisc 3.xx 的?文
发表于: 2006-5-31 19:08 6860

[求助]?求翻诅呃篇SafeDisc 3.xx 的?文

2006-5-31 19:08
6860
?求翻诅呃篇SafeDisc 3.xx 的?文

俄吝斯遮 thx

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 332
活跃值: (499)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
2
俄吝斯遮,期待!
2006-5-31 22:16
0
雪    币: 2108
活跃值: (208)
能力值: (RANK:1260 )
在线值:
发帖
回帖
粉丝
3
同样期待会俄语的朋友出手。
2006-6-1 13:27
0
雪    币: 320
活跃值: (104)
能力值: (RANK:180 )
在线值:
发帖
回帖
粉丝
4
我用?上翻诅 Ru->EN 弈的不是很?? 腠邋字很多但彦面很多都是softICE的Debug方法 Sice我不熟 所以?是希望大家翻一下 THX
目前只整理到4章 那?我看我?弈Ru->EN
大?家?忙一下 EN->CH
如果照英文文法一定看不懂 所以希望熟SoftICE的大大?一下 THX
-----------------------------------------
=======================================================================
=============手??? (NFSU2 - Safedisc v 3.xx)===================
=======================================================================

作者:           mr_magic
弈傥:           rep0A
日期:           3.12.2004
目?:           Speed2.exe
大小:           5.987.981 Bytes
工具:           SoftIce, IceExt 0.65, PEditor 1.7, Procdump 1.6, Imprec 1.6f, Hex Workshop, Code Fusion
肺?:           ??

Mini Image & 原始 speed2.exe
42eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4y4W2L8X3c8K6M7r3q4U0k6g2)9J5k6h3y4G2L8g2)9J5c8X3k6A6L8r3g2Q4x3V1j5&6K9o6x3^5M7r3R3`.

SafeDisc 3 RU&EN Docs

d73K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4y4W2L8X3c8K6M7r3q4U0k6g2)9J5k6h3y4G2L8g2)9J5c8X3k6A6L8r3g2Q4x3V1k6F1K9s2u0@1y4X3t1`.

1. 前言
=================

?先??原始 SafeDisc CD 如果?CD的? 可至 GameCopyWorld 或其他地方下蒌一?可??咣?的 Mini Image

用 Daemon Tools 或 Alcohol 120% ?模?.

2. ??
==================

以PE??器檫??段, 已知stxt774跟stxt371?Safedisc的?段

stxt774 ?防罪劫?
stxt371 ?Loader?段

完全清除safeDisc後可?他去除

在蒌入Debug前 ?先把 "代瘁?段 .text(.Code) 跟Import Table ?段 .rdata 的?段加入可?的?性





3. Restoration Import
===============================

With the explanation of the restoration of import I will describe only about necessary, since this did not change after my

last splint

Well it is agreeable, give let us look on YE.P. Here we will use PEditor for that, so that SoftIce(.SI) would stop after the

load of program. For this press on "break'n'enter" and place point of discontinuity to Int03.

:bpint3

If we now press on "RUN", softays will show us this:

0093309E   55               PUSH EBP
0093309F   8BEC             MOV EBP,ESP
009330A1   60               PUSHAD
009330A2   BB 9E309300      MOV EBX,OFFSET speed2.{ModuleEntryPoint}
009330A7   33C9             XOR ECX,ECX
009330A9   8A0D 3D309300    MOV CL,BYTE PTR DS:[93303D]
009330AF   85C9             TEST ECX,ECX
009330B1   74 0C            JE speed2.009330BF
009330B3   B8 13319300      MOV EAX,speed2.00933113
009330B8   2BC3             SUB EAX,EBX
009330BA   83E8 05          SUB EAX,5
009330BD   EB 0E            JMP speed2.009330CD
009330BF   51               PUSH ECX
009330C0   B9 59319300      MOV ECX,speed2.00933159
009330C5   8BC1             MOV EAX,ECX
009330C7   2BC3             SUB EAX,EBX
009330C9   0341 01          ADD EAX,DWORD PTR DS:[ECX+1]
009330CC   59               POP ECX
009330CD   C603 E9          MOV BYTE PTR DS:[EBX],0E9
009330D0   8943 01          MOV DWORD PTR DS:[EBX+1],EAX
009330D3   51               PUSH ECX
009330D4   68 09309300      PUSH 00933009
009330D9   33C0             XOR EAX,EAX
009330DB   85C9             TEST ECX,ECX
009330DD   74 05            JE 009330E4
009330DF   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
009330E2   EB 00            JMP 009330E4
009330E4   50               PUSH EAX
009330E5   E8 76000000      CALL 00933160                 ;解?矿代瘁?理
009330EA   83C4 08          ADD ESP,8
009330ED   59               POP ECX
009330EE   83F8 00          CMP EAX,0                     ;??解?矿是否有邋锗?
009330F1   74 1C            JE 0093310F                   ;正催?跳
009330F3   C603 C2          MOV BYTE PTR DS:[EBX],0C2
009330F6   C643 01 0C       MOV BYTE PTR DS:[EBX+1],0C
009330FA   85C9             TEST ECX,ECX
009330FC   74 09            JE 00933107
009330FE   61               POPAD
009330FF   5D               POP EBP
00933100   B8 00000000      MOV EAX,0
00933105   EB 97            JMP {ModuleEntryPoint}
00933107   50               PUSH EAX
00933108   A1 29309300      MOV EAX,DWORD PTR DS:[933029]
0093310D   FFD0             CALL EAX
0093310F   61               POPAD                         ;the stack clean
00933110   5D               POP EBP                       ; ""
00933111   EB 46            JMP 00933159                  ;擂理跳弈
00933113   807C24 08 00     CMP BYTE PTR SS:[ESP+8],0
00933118   75 3F            JNZ 00933159
0093311A   51               PUSH ECX
0093311B   8B4C24 04        MOV ECX,DWORD PTR SS:[ESP+4]
0093311F   890D 53319300    MOV DWORD PTR DS:[933153],ECX
00933125   B9 31319300      MOV ECX,00933131
0093312A   894C24 04        MOV DWORD PTR SS:[ESP+4],ECX
0093312E   59               POP ECX
0093312F   EB 28            JMP 00933159
00933131   50               PUSH EAX
00933132   B8 2D309300      MOV EAX,0093302D
00933137   FF70 08          PUSH DWORD PTR DS:[EAX+8]
0093313A   8B40 0C          MOV EAX,DWORD PTR DS:[EAX+C]
0093313D   FFD0             CALL EAX
0093313F   B8 2D309300      MOV EAX,0093302D
00933144   FF30             PUSH DWORD PTR DS:[EAX]
00933146   8B40 04          MOV EAX,DWORD PTR DS:[EAX+4]
00933149   FFD0             CALL EAX
0093314B   58               POP EAX
0093314C   FF35 53319300    PUSH DWORD PTR DS:[933153]
00933152   C3               RETN
00933153   72 16            JB 0093316B
00933155   61               POPAD
00933156   1360 0D          ADC ESP,DWORD PTR DS:[EAX+D]
00933159   E9 9388E2FF      JMP 0075B9F1                ;前往 OEP!!!

Thus nothing new after Safedisc v2. No, there is one small change: We can place breykpoynt directly on the leap on OEP.

Safedisc this will no longer note (31 fellows, you ukhud'sheli your zashitu:D) means

:bpx #00933159

Carefully, before we will begin to go further, we must change int3 which we they placed in EP to the initial byte.

:eb eip 55

Now we press to F5, we jingle, we press one time F8 and now we are found on OEP. Voobshcheto would be everything good, all

sections are unpacked and we can dampit', if Safediss did not put to us stick in the wheels... pear??? Hehe, let's fix dat...

first we must it will care about not the complete import.

That the import is cut, it is possible to learn very easily, if we look on IAT (kotora4 it is located in the begin section ".rdata").



RVA to API to functions must be read to back on before, this indicates that the address of the first import on the picture it

is equal to 77E53835. This address on my OS belongs to Kernel32.RaiseException. We immediately see that import Kernel32 it is

cut, it means we should it restore. Unfortunately this does not completely decrease our work...

Entire import, which begins with 0174/0175 this the cut import. We will memorize this for our import fiksiruyushigo of the

code.

Ktomu-zhe we will memorize in what part of IAT it is encountered this cut import. In me this the approximately first 500h

bytes.

Kak was already described in my past article, we wake to write our code in PE Header+500h (or to enter if you more greatly

pleases itself to use Code Snippet Creator or Hiew).

In order to to understand the following steps, I advise you to pozakhodit' into the nekot.orye perenapravlennye calls. Call

relating to the first perenapravlennomu import in IAT (00783004) appears thus:



If we into it enter we let us see here this:



To procedure Safedisc-a, which removes that cut RVA and is caused the appropriate import, 3 parameters are transferred. 2 of

them we can see on the picture. This is two PUSH-a(0174D582, 0174D58A). The third is transferred by "invisible" through the

stack. This is address, out of which was caused our cut import + 6, consequently address afterward "Call [ 00783004 ]".

So occurs therefore- that Call this nothing another as leap and Push $the address of the leap + 6' in one. This fact forces

us to restore in the section.text not only IAT(kak in many zashit), but also Call [ref]'.

Some imports appear for us equally after perenapravlenniya, therefore- that they indicate the identical address in IAT. Since

procedure Safedisc-a for restoring the import includes address Call[ref]' into the calculation, different API- functions

are caused.

Give let us look to procedure itself, which begins with 6678D3BA. If we are sufficient to for long treysim, we will note that

these 3 places those more meant:



Here it is checked, there was obrabatyvayushchayusya RVA already vostanovlenna. If no, we pass leap and she

vostanavlivayetsya. If yes, that is used already imeyusheyesya. We propatchim this procedure so as to our RVA constantly

vostannavlivalis' renovate. For this we will make from the conditional leap unconditional. This will give to us lut'she to

feel itself ;)



As we see, the second checking is carried out, it will be restored before the fact RVA. (here we zanopim leap). In conclusion

to stack is transferred through PUSH number DLL and functions, which before this were calculated from our three parameters

and RVA is restored in represented Call-e.



This place for us is the most interesting, therefore- that this is the end of the procedure. Stack is cleaned and when we

treysim through RET, we are found in the beginning of correct API function. This means that before we protreysim through RET,

upper dword in our stack is that most correct RVA for our import. This we is utilized in our code. For this we will write on

address 6678D6AB

My let us divide our code for restoring the import into two parts. The first is necessary therefore- that programmers from

Macrovision they noted trick with three parameters. Thus first we must we wake write down in not the necessary place

temporary, restored IAT, in which there are no cut imports. We will later write down it above the old, which to us is still

necessary,

in order to to restore section.text. We will search entire section.text to object Call[ref]'.s, which cause those cut RVA

and to correct their purposeful addresses on the new symbolic addresses of temporary IAT, so in order to they posli of

perepisaniya IAT caused correct import.

As the suitable place for the creation by the temporary IAT I see Safedisc Loader Section. Thus we again will look in this

section, in order to to have all values for our code.

_ReturnNachSafedisc:                      ;(_To vozvrashcheniye Safedisc)
mov esp, dword ptr [ebp+0C]               ;Stack cleans, like the function
popad                                       ;at the end of procedure Safedisc-a which ended
popfd                                       ;izza of leap.
pop edx                               ;Preserves the correct RVA in edx
cmp dword ptr [esp], 00400500               ;would leave we in the case of RETurn-a
jl _KorrigiereStack                       ;in our code?
cmp dword ptr [esp], 00401000               ;If no, that kor.pigiruyet stack.
ja _KorrigiereStack                       ;(this becomes necessary, therefore-that
ret                                       ;we is utilized additional PUSH

_KorrigiereStack:                       ;(_Vosstanavlivayu Stack)
add esp, 4                               ;in the second part of our code,
ret                                      ;in order to to place exit point.

_CODEPART1:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;; Creation by the temporary IAT ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov ecx, 00782FFC                       ;beginning IAT-4
mov ebx, 00932FFC                       ;Safedisc Loader Section-4

_Start:                                      ;(_Start:)

add ecx, 4                               ;I make further with the following RVA
add ebx, 4                               ;I also increase the address of our temporary IAT
cmp ecx, 00783500                       ;we already processed 500h it was byte?
ja _EndeBuildIAT                      ;(_End Compilations IAT)

mov edx, dword ptr [ecx]               ;I put RVA the processed import in edx
cmp edx, 01740000                       ;RVA in
jl _BuildIAT^                              ;(_Compilation IAT)
cmp edx, 01760000                       ;Safedisc Range?
ja _BuildIAT                              ;(_Compilation IAT)
call edx                               ;if yes, I cause import in order to to leave the correct RVA

_BuildIAT:                              ;(_Compilation IAT)

mov dword ptr [ebx], edx               ;I put the correct RVA in the temporary
jmp _Start

_EndeBuildIAT:                              ;(_End Compilations IAT)

jmp _CODEPART2

_CODEPART2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;; Restoration Call [.ref]s ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax, 00401000                       ;beginning of the section .text

_SucheNachCallRefs:                      ;(_Search CallRefs)

cmp word ptr [eax], 15FF               ;The first two bytes belong to the urgent function FF15?
je _CallRefGefunden                       ;(_CallRef found)        If yes, I check Call [.ref]

_SucheNachCallRefsLoop:               ;(_Search CallRefsLoop)

inc eax                               ;If no, I make further with the following function
cmp eax, 00782FFF                       ;We reached the end of the section .text?
jne _SucheNachCallRefs                      ;(_Search CallRefs)
jmp _AlleCallRefsGefixt               ;(_Everything CallRefs They are restored)

_CallRefGefunden:                      ;(_found CallRef)

cmp dword ptr [eax+02], 00783000      ;Read address, in
jl _SucheNachCallRefsLoop             ;(_Search CallRefsLoop)
cmp dword ptr [eax+02], 00783500      ;the first 500h is byte by our IAT?
ja _SucheNachCallRefsLoop             ;(_Search CallRefsLoop)

_CheckobGemangleterCallRef:           ;(_CheckobGemangleterCallRef)

mov ecx, dword ptr [eax+02]               ;I put the address of import in IAT in ecx
mov ecx, dword ptr [ecx]               ;I put RVA urgent import into ecx
cmp ecx, 01740000                     ;RVA in
jl _SucheNachCallRefsLoop             ;(_Search CallRefsLoop)
cmp ecx, 01760000                       ;Safedisc Range?
ja _SucheNachCallRefsLoop             ;(_Search CallRefsLoop)

Push _FixCallRefReturnPoint           ;if yes, I place our Return Point
add eax, 6                            ;I calculate 3. Parameter (Call [.ref] Offset+6)
push eax                              ;And push-uh it
sub eax, 6                            ;I again place beginning Call [.ref]s in eax
jmp ecx                               ;and I carry out SD Routine, in order to to leave the correct RVA

_FixCallRefReturnPoint:               ;(_Restoration ReturnPoint-aCallRef-a)

mov ebx, 00933000                     ;I put the beginning of the temporary IAT in ebx

_FixCallRefLoop:                      ;(_Restoration CallRefLoop-a)

cmp dword ptr [ebx], edx              ;I search for the urgent RVA in the the temporary IAT
je _FixCallRef                        ;(_Restoration CallRef-a)
add ebx, 4                            ;I check the following import in the the temporary IAT
cmp ebx, 00933500                     ;we reached the end of the temporary IAT?
jl _FixCallRefLoop                    ;if no, I make further
jmp eip                               ;In other case I transfer control to the search for the errors

_FixCallRef:                          ;(_Restoration CallRef-a)

sub ebx, 00933000                     ;I put symbolic address measured in the beginning IAT in ebx
add ebx, 00783000                     ;and to the future address if temporary IAT was kopirovana in the correct place
mov dword ptr [eax+02], ebx           ;and I renew Call[.ref ] with the new address of the import
jmp _SucheNachCallRefsLoop

_AlleCallRefsGefixt:                  ;(_Everything CallRef-bi They are restored)
jmp _CODEPART3

Unfortunately the import was of perenapravlen not only this means. There is still the second method. There exist Longjumps,

which were once Call [.ref]-ami, which now cause section stx774. in principle this we could be and Call-bi to Jumptables, but

this is not in NFSU2. We can see very easily this, therefore- that byte after leap always Junk Byte therefore- that initially

standing at this place Call [ref] was one byte longer than leap. Caused izza of leap procedure Safedisc-a constantly jumps

over this byte. Example for similar Long Jump-a:



We see that the instruction after leap does not have a sense. This Voobshcheto must appear thus:



If we protreysim into perenapravlennyy Long Jump, then we wake not long time it is located in section stx774, after RET-a we

will leave here:



Means this procedure it makes almost also the very that also Call[.ref]s, with one small difference, that 3 parameter is put

by hand, therefore- that is carried out Jmp and not Call. After this, is caused our procedure restoring RVA, which we already

propatchili. Thus we write further:

_CODEPART3:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; Restoration of the perenapravlennykh leap;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax, 00401000               ;Begin section .text

_SucheNachLongJumps:            ;(_Search LongJump-OB)

cmp byte ptr [eax], E9          ;possibly we deal concerning some Long Jump-OM?
je _JumpGefunden                ;(_Jump found)

_SucheNachLongJumpsLoop:        ;(_Search LongJumpLoop-OB)

inc eax                         ;check the following byte
cmp eax, 00782FFF               ;We did reach the end?
jne _SucheNachLongJumps         ;(_Search LongJumpLoop-OB)
jmp _CODEPART4                  ;Restoration perenapravlennykh Call-OB

_JumpGefunden:                  ;(_Jump found)

mov ecx, dword ptr [eax+01]     ;I put dword the value of distance into ecx
add ecx, eax                    ;I add it with the urgent address
add ecx, 00000005               ;and with the long of leap = the Address- purpose
cmp ecx, 00930000               ;Address- purpose in
jl _SucheNachLongJumpsLoop      ;(_Search LongJumpLoop-OB)
cmp ecx, 00933000               ;section stx774?
jnb _SucheNachLongJumpsLoop

push _LongJumpFixReturnPoint    ;If yes, to vstavlyau our Return Point
jmp ecx                         ;and I calculate the correct RVA for our import

_LongJumpFixReturnPoint:

mov ebx, 00933000               ;I put the beginning of our vremmenoy IAT into ebx

_LongJumpFixLoop:

cmp dword ptr [ebx], edx        ;and I search for in it our urgent RVA
je _LongJumpFix                 ;it found, then I jump
add ebx, 00000004               ;if it did not find, I check the following dword
cmp ebx, 00933500               ;we did reach the end?
jl _LongJumpFixLoop             ;if no, I make further
jmp eip                         ;infinite leap, the hand finishing of the errors

_LongJumpFix:

sub ebx, 00933000               ;Puts the symbolic address, izmeryanyy in the beginning IAT in ebx
add ebx, 00783000               ;and future address if vremyanaya IAT was kopirovana into the correct place

_LongJumpIstCallRef:            ;(_LongJump-CallRef)

mov word ptr [eax], 15FF        ;convert Long Jump in Call [.ref]
mov dword ptr [eax+02], ebx     ;with the suitable address of our vremyannoy IAT
jmp _SucheNachLongJumpsLoop     ;and I search for the following Long Jump

Fuf, finished with the familiar. Now we can rewrite the old IAT to the new.

:m 00933000 L 500 00783000

All -we are still distant from the game without Saferdisc-a, therefore- that Safedisc-a has 2 new technologies, not to give

to work to our dump. If you wrote in SI, then they must preserve your code:

:!dump \??\C:\nfsu2.patch.dat 00400 500

in order to with the new start of game not to write with its ponovoy, but it is simple to load:

:!loadfile \??\C:\nfsu2.patch.dat 00400500

If the code was written in Hex Editor-e, then this certainly made must not be ;)

4. Restoration internal, perenapravlennykh call
===============================================================

The following explicit attempt Safedisc-a to spoil to us life these are the stifling bytes, which were substituted on THE CC

(instruction int3). If we in SI place

:bpint3

and let us normally neglect game, then after 2 bryakov we will pause at this place:



If we pressing F8 by protreysim instruction Int3, then let us leave into module ntoskrnl. Give to now potreysim the following

Call jumping over rest, so we will reach the end of the procedure:



If we protreysim through IRETD, then let us leave into our "Speed2.exe", truth by two bytes are further, it means before two

following int03 instructions. If we shityu protreysim and through these, we see also the very.
If we leave our bpx by still active, then we will be able to see that if at one place they stand three int3 tyuey podryat,

then after procedure ntoskrnl in the section of .text are placed correct bytes instead of CC. also if we we reach the place

from 4-mya int3, which we already once passed, then correct bytes will be later inscribed into the segment of the code.

For example these bytes:



Certainly to us it is not must so it takes a long time to await, until we pass one and also place two times, but it is simple

to take away in EIP 4. Since we are too lazy in order to to protreysit' entire procedure ntoskrnl, then we will think through

what function API can it is produced copying... Accurately! through Kernel32.WriteProcessMemory.

Give after we they left to OEP let us place breykpoynt on

:bpx writeprocessmemory

Aha, we jingled. If we look to the registers, we will see, that ebx only in which is an address of our speed2.exe. We means

we introduce:

:u ebx



Mda... Unfortunately in the address not the fact that we expected - int3, but "Call 00401089". But all -equal appears

interestingly... give let us introduce

:p ret

in order to to leave function API. Now we see that it was caused Safedisc-om. Give to potreysim procedure without entering

into Call-bi, until we reach this place:



The call of function API "RtlLeaveCriticalSection" shows that procedure it concludes. We means protreysim into the following

Call.



Since the address of stack now in eax- e is contained, then Jmp on EIP jumps there. We see:



It means stack it is corrected and we conclude after RET-a at that place, on which us in general had to derive Call:



Thus we learned, that after the correction of stack and before RET- ohm upper dword in the stack this is the address of the

present purpose Call-a. But therefore- that procedure Safedisc-a such good and with the aid of Kernel32.WriteProcessMemory

copies not correct Call to the correct, then we more should by this be occupied. How we will find other perenapravlennye

Call-bi? The solution will arrive, when we second time jingle on Kernel32.WriteProcessMemory and look on ebx. What we do see?

To XeXe, again "Call 00401089"...

So that we must make:
1. to search the section of .text to the object "Call 00401089"
2. will care that we after the procedure Safedisc-a again would enter into our code.

In the first point it is necessary to focus attention on that, in order to Call-bi as Jmp- y not were static. This means that

we, having Hex values, simply do not read purposeful address, but must its raschityvat'(Adres+5+.dshord ptr from [Adres+5]).

In the second point it is necessary to focus attention on that, in order to the end of the procedure was in the stack. Since

it again is copied, then the code at the end of the procedure, with each call 00401089 is written there on the new. Them it

surely was desirable by this to avoid patch (well fellows this PRAVDA weakly...)

Izza of this we must patchit' still more, when we are found not in the stack into procedures SafeDisc-a. I made this,

although we have other possibilities :)



We write "mov dword ptr [ebp-4], _ReturnPointInternCall;(_ReturPoint Vtutrennego.Call- a)" in the address "6673E11C" and

nopim rest to "Jmp[ebp-4]"

In our "_ ReturnPointInternCall: ;(_ReturPoint Vtutrennego Call-a) "we must, as in procedure SafeDisc-a, to restore stack but

we do not want to leave to the address to which voobshcheto shows Call, but to our further code. It means we should restore

stack on other. But against this on- in more detail. Let us first write down that the fact that we already know:

_CODEPART4:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; Vostanovleniye perenapravlennykh calls;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax, 00401000

_SucheNachCalls:                ;(_Search Call-OB)

cmp byte ptr [eax], E8                 ;There can be this Call?
je _CallGefunden

_SucheNachCallsLoop:                ;(_Search CallLoop-OB)

inc eax                         ;check the following byte
cmp eax, 00782FFF                 ;We did reach ends?
jl _SucheNachCalls                ;(_Search Call-OB)

jmp _CODEPART5                         ;jump to our last code :)

_CallGefunden:                        ;(_Call found)

mov ebx, dword ptr [eax+01]         ;Gunstock to dlinnu Call-a in ebx
add ebx, eax                         ;add it with the address
add ebx, 00000005                 ;And it is byte with a quantity Call-a
cmp ebx, 00401089                 ;this "Call 00401089"?
jne _SucheNachCallsLoop                ;(_Search CallLoop-OB)

call eax                         ;if yes, then I cause and substitute it

jmp _SucheNachCallsLoop                ;(_Search CallLoop-OB)

In order to to now have correct value for our stack, it is necessary to potreysit' entire code, until we reach the place

where it is preserved:



Means we pass "push esp, pushfd, pushad" we regard value now in esp. Aha, 0012FF90. Teper6 there is everything that to us

necessarily.

_ReturnPointInternCall:        ;(_ReturPoint Vtutrennego Call-a)

mov esp, 0012FF90                 ;we want in order to in all registers
popad                                 ;there was also the very that also in the retention
popfd                                 ;when stack stood on 0012FF90.
pop esp
mov esp, 0012FFC0                 ;Now we should dispose it so in order to
ret                                 ;in it remained correct address for RETurn-a.

In general "mov esp, 0012FFC0" could be and "add esp, 4" or "add esp 8", this each has Call-a differently. Therefore I

selected reliable version.

Entire vosstanovlenno? It is good, then it is possible to dampit' ". First we make Procdump-om "Full Dump" with all "PE

Rebuilding" opqi4mi, also, WITHOUT the restoration of import. This we still will make. To kt.omu-zhe we will make a dump of

the section.text:

:!dump \??\C:\nfsu2.text.section.fixed.dat 00401000 00382000

5. restoration of stifling it is byte:
=========================================

This time we truth wake to restore stifling bytes. In principle we could for this simple to play a little 24 hours. Although this would deliver to us the heap of the pleasures, not it would be to 100% reliably and it can be we they would note too late some bytes which yet not tyuey vostanovilis'.

As we already learned, all stifling bytes are copied through the the special Exception Handler in ntoskrnl.exe not later than with the second call.As there would be always best anything if we obishchem the section of .text to object int3s, let us then carry out them in order to to rewrite to the correct bytes and it is reverted to our code... And here we encounter problemmoy. We truth do want to propatchit' WindowsNT Kernel??? To definitely net(pochti would tear my OS... of:.Kh) and that before this? Mmmmm... before this the section of .text. Surely we will not be able to go around it by us destruction. Therefore we made a dump.

My first idea was, after each int3 or after each block int3 write down C3(instrukqi4 RET) and cause it. But then we again encounter problemmoy. In our stifling bytes can prove to be pryzhki(kak we they memorized in our first example). Second problemma was, to rewrite everything except Int3s bytes C3. means even after leap we let us prove to be on RET-e... But also in this idea est6 the difficulty:

We indeed must somehow verify, this stifling byte or is simple the byte of another instruction. In order to better to understand that I have in the form, you must with the command of softaysa

s 00401000 l ffffffff cc cc

to search the section of..tekht. You will note that in other functions sufficiently much the CC it is byte. For example:



If we wander a little into the bottom or upward, we will see the present function:



If we try, nevertheless to neglect these Int3s, then Exception Handler does not copy these bytes, but simply is opened NT Exception Dispatcher. Appears MessageBox, that there was Exception and game is shut.

Also with the search of the section of .text we wake to frequently encounter with this:



Here we deal concerning the special case, in which are always encountered NOP and 5 int3s confronting RET-om. If we will carry out these Int3s, that they to be adopted by the special Exception handler-om and it will rewrite them to 9090909090. Why the special case? Well, this we will see when let us try to carry out the following Int3s, about which we know that this stifling bytes. They not will be rewritten. This seems by a good motion from side Macrovision. These bytes NEVER are carried out with the normal circumstances, therefore- that they are encountered only after podprotsedur and before them always stands RET. Means if we them we will carry out, that is sewn it learns about the fact that we we want it to break and us more it will help in no way...

Why I do write that it does seem? To khekhe, since we about this know, we simply will search entire section of .text to the object of chain it is byte "C3 CC CC CC CC CC 90" and zanopim it. To us there remains only to solve problem with the fact, as we learn that obtained Int3s stifling bytes. It is necessary not much to look for this, since we should find as much as possible present stifling it is byte in order to to note similarity.

We first note, that all present stifling bytes not shorter than two it is byte, in addition to this before the present stifling bytes frequently stands Call[ref], truth not always. But if we look well that let us see, that is a little above the stifling byte it stands similar Call[ref]. The very great distance which I saw between the first Int3 block to FF beginning Call[ref]s, were 2C byte. Pravda it surely changes with each game and version.

It means our plan it is such:
We will search the section of .text to the object OF THE CC it is byte and FF15 words. However, potential Call[ref].s must be still checked, they do read our IAT. Everything except our Int3s and checked Call[ref].s will be rewritten by instruction C3. Now we sdampim the section of .text After this, we will carry out everything Int3s, which have the maximum distance of -2C to Call[ref] and by sdampim again when everything will be restored. Now we can compare both files with any Patchengine as, for instance, Code Fusion and write down changes in our above sdamplennuyu section of .text.

If we began all this to write, that we would stumble on two problemmy. I immediately will describe about them, in order to to free us from not the necessary work:

1. Problemma with three int3s
2. Problemma with seven int3s

Restoration of several, the first stifling bytes it functions excellently. However, first problemma appears sufficiently rapidly and only when are carried out three int3. Therefore- that some Int3s of these triple blocks this "add esp, XX"(kotorye have a length into three bytes). Since they after record are carried out in the segment, that RETurn the address of stack correct and with by following RET-e we end in nervane. We means they must before we let us carry out any Int3, to place after all triple blocks Int3- eating leap to the stack- correcting procedure.

Second problemma appears at the end of the section of .text. To nekotory.e Int3 blocks this "mov dword ptr [esi], XX". Surely some they will ask "A in what strictly of problemma? Well, give then let us look on esi. At it the value lies 00000000, which is not correct address for the retention, for which our game does not have right of record. Result - termination... Now we can enter in the beginning of our Int3- reducing procedure of 00933000 (adres Safedisc Loader Section) in esi.

Everything is understandable? Then we write down:

_CODEPART5:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; restoration of stifling it is byte ;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov esi, 00933000                           ;Soot address with the rights of record in esi
mov eax, 00401000                           ;Begin section .text

_SucheNachInt3sUndCallRefs:              ;(_Search Int3 and CallRefs)

cmp byte ptr [eax], CC                      ;Urgent function this Int3?
je _Int3Gefunden                         ;(_found Int3)
cmp word ptr [eax], 15FF                 ;or Call [.ref]?
je _CODEPART5CallRefGefunden             ;(_CODEPART5 found CallRef)

_UeberschreibeByte:                      ;(_copy the bytes)

mov byte ptr [eax], C3                   ;If no that it copies them
inc eax                                  ;and I make further with the following byte
cmp eax, 00782FFF                        ;We are ready?
jl _SucheNachInt3sUndCallRefs            ;(_Search Int3 and CallRefs)

jmp _SucheNach3erBlockInt3s:             ;(_Search For the block Int3-e in Three bytes)

_Int3Gefunden:                           ;(_found Int3)

cmp word ptr [eax+04], 90CC              ;We deal concerning the trick from Macrovision ?
je _MacrovisionTrickGefunden             ;(_found Trick From Macrovision)
inc eax                                  ;In other case urgent byte copies and it makes further
jmp _SucheNachInt3sUndCallRefs           ;(_Search Int3 and CallRefs)

_MacrovisionTrickGefunden:               ;(_found Trick From Macrovision)

mov dword ptr [eax], 90909090            ;nopit trick from Macrovision
mov byte ptr [eax+04], 90
add eax, 00000006                        ;check the following function
jmp _SucheNachInt3sUndCallRefs           ;(_Search Int3 and CallRefs)

_CODEPART5CallRefGefunden:               ;(_CODEPART5 found CallRef)
cmp dword ptr [eax+02], 00783000         ;read our potential Call[ref]
jl _UeberschreibeByte                    ;(_copy the bytes)
cmp dword ptr [eax+02], 00784000         ;address from our IAT?
ja _UeberschreibeByte                    ;(_copy the bytes) ;if no, that copies it
add eax, 00000006                        ;in other case I leave by its free
jmp _SucheNachInt3sUndCallRefs

_SucheNach3erBlockInt3s:                 ;(_Search For the block Int3-e in Three bytes)

mov eax, 00401000                        ;Begin section .text

_SucheNach3erBlockInt3sLoop:             ;(_Search For the block Int3 Loop-ob in Three bytes)

cmp word ptr [eax], CCCC                 ;two are located on the urgent address Int3-a?
je _2Int3sGefunden                    

_NaechstesInt3:                          ;(_Following Int3)

inc eax                                  ;In other case I increase the address
cmp eax, 00782FFF                        ;End?
jl _SucheNach3erBlockInt3sLoop           ;(_Search For the block Int3 Loop-ob in Three bytes)

jmp eip                                     ;Eternal cycle, now we should sdampit' the section.text

                                            ;(nfsu2.stolen.bytes.not.recovered.dat)

jmp _SucheNachInt3s                      ;(_Search Int3-eb)  ;and to continue with the last part :)

_2Int3sGefunden:                         ;(_Two are found Int3)

cmp byte ptr [eax+02], CC                ;Third byte also Int3?
jne _NaechstesInt3                       ;(_Following Int3)  ;If no, search for further.
cmp byte ptr [eax+03], C3                ;This the latter or afterward be still
jne _NaechstesInt3                       ;(_Following Int3)  ;If not latter, search for further
cmp byte ptr [eax-01], CC                ;Is there before that checked still Int3-and?
je _NaechstesInt3                        ;(_Following Int3)  ;If yes, search for further

add eax, 00000003                        ;Soot address afterward Int3-a in eax.
mov ebx, eax                             ;Soot the value eax-a in ebx
add ebx, 00000005                        ;To this I add the length Long Jump-a
sub ebx, _CorrectStack                   ;and I take away the address of the purpose
imul ebx, FFFFFFFF                       ;We want to jump back, it means we should this all multiply on (-1)
mov byte ptr [eax], E9                   ;I write instruction for Long Jump-a
mov dword ptr [eax+01], ebx              ;and the suitable length Jump-a
jmp _NaechstesInt3                       ;(_Following Int3)

_CorrectStack:

cmp word ptr [eax], C483                 ;3 stifling bytes were "add esp, XX"
jne _MussNichtKorrigiertWerden           ;(_It Must not Be Restored)
movzx ebx, byte ptr [eax+02]             ;I write "XX" in ebx
sub esp, ebx                             ;and I take away this value from the stack

_MussNichtKorrigiertWerden:              ;(_It Must not Be Restored)

ret                                      ;return back

_SucheNachInt3s:                         ; (_Search Int3-eb)

mov eax, 00401000                        ;Begin section .text

_SucheNachInt3sLoop:                     ;(_Search Int3 Loop-ob)

cmp word ptr [eax], CCCC                 ;can be to aktual'ny.e two bytes stifling
je _TesteInt3                            ;(_check Int3)   ;if yes, check them
inc eax                                  ;in other case I check the following
cmp eax, 00782FFF                        ;We reached the end of the section .text?
jl _SucheNachInt3sLoop:                  ;(_Search Int3Loop-ob)

jmp eip                                  ;the bezkonechnyy cycle, We COULD Make This!!!

_TesteInt3:                              ;(_check Int3)

mov ebx, eax                             ;write the value eax-a in ebx
sub ebx, 0000002C                        ;and I take away away from this the maximum permissible distance to Call[.ref]-y

_TesteInt3Loop:                          ;(_check Int3 Loop)

cmp word ptr [ebx], 15FF                 ;There is whether any Call[.ref] in the urgent distance to Int3
je _CalleInt3                            ;(_cause Int3)

inc ebx                                  ;If no, I decrease the distance
cmp ebx, eax                             ;We verified entire maximum permissible distance?
jne _TesteInt3Loop                       ;(_check Int3 Loop) ;If no, to the ides further
add eax, 00000002                        ;In other case I do not carry out urgent Int3
jmp _SucheNachInt3sLoop                  ;(_Search Int3Loop-ob)  ;and I search for further

_CalleInt3:                              ;(_cause Int3)

pushad                                   ;preserve all registers
pushfd                                   ;and the stack.
call eax                                 ;cause address Int3-a, in order to restore the stifling byte
popfd                                    ;restore the stack
popad                                    ;and all registers
cmp word ptr [eax], CCCC                 ;Stifling bytes were restored
je _CalleInt3                            ;(_cause Int3)  ;If no, cause them again
add eax, 00000002                        ;In other case I search for the following
jmp _SucheNachInt3sLoop                  ;(_Search Int3Loop-ob)

Fuf... here almost and everything. With the fulfillment of procedure we should just in case place Breakpoint on NT Exception Dispatcher, which is called when we we attempt to restore stifling bytes which them in reality they are not.

:bpx KiUserExceptionDispatcher

Opa, we see what, if we neglect our code, we sometimes will jingle on KiUserExceptionDispatcher. If we now introduce

:u eax

that we will see that on our criteria these bytes they must be stifling. Somewhat higher Int3-ob is Call that leading to Kernel32.CreateMutexA. The matter in the fact that after some address of stifling it is byte more no. In NFSU2 this approximately 00730000. It means everything restored. In softayse to us there remained only to sdampit' section.

:!dump \??\C:\nfsu2.stolen.bytes.recovered.dat 00401000 00382000

Now we can shut softays. Instead of this we will open Code Fusion and will create new project. In the line "Patched File:" we will point out "Any File" after harvesting to the sootvesvuyushchuyu button. With "Data to patch" we will select "File Compare" and by attitude of tuning as ukazanno below:



As original file we will point out our section of .text, which was sdamplena after perepisaniya bytes C3. As propatchenyy file we will point out our section of .text, in which we restored stifling bytes. We will remove jackdaw with "Save Original Data in project". So we will attain that in order to we could renew section .rdata(improt/vnutrenniye Call-bi) with that created patchem.

Means if we we press on "Compare", that we will obtain the list of differences, with which we now can create patch "Int3fix".

This ekseshnik we to srazu-zhe to vyzovim and will point out our restored section of .text as Target File (nfsu2.text.section.fixed.dat). After file we renewed we can s grow prettier conscience name it "nfsu2.text.section.fully.fixed.dat" :)

6. Recompilation
===============================

Now we will open our Full Dump made somewhat higher in Hex Worshop- e, let us leave for address 1000,

vyb.er.em Edit = Select Block and let us point out as value "00381821"(.Raw Size of the section of .text).

Now we can harvest Del(.entf) in order to to remove entire section.

Now give let us open our "nfsu2.text.section.fully.fixed.dat" in the same Hex by Workshop- e, vydilim in it also 00381821 it is byte, we copy them and will put into the address 1000 Full Dump- A

To ktomu-zhe we can the latter 7000h ba1tov(kogda- that those belonging to both sections Safedisc- A) simply remove all this preserve.

From PEditor- ohms we will move away from Header- A still and last two sections, which we already removed from the file.

Stoyte, we seems something they forgot to make...Accurately, we yet not perekompilirovali import.

In order to to make this, we should again open Speed2.exe, is jingled on OEP and to neglect our patch for the import (only not for the stifling it is byte;.D...) and in conclusion to rewrite the old IAT to the new.

Now we should open Imprec, select Speed2 in the list of active processes, introduce OEP and harvest on "IAT autosearch". After this, on "Fix Dump" and to select our dump... IT IS PREPARED!!!

To us there remained only to perekompilirovat' our exe with LordPE, PEditor- ohm or PE Rebuilder- ohm.

7. Conclusion
=========================================

Thus, long tutorial approaches toward the end. I hope to you it was

pleased to read and you learned to something.

Gr6@4.e an (no particular Order): das gesamte CIP Team

(ZeroJump.BigDragon, *.RemedY *),old genius r!.sc, Peex, quake_.qer und

alle anderen aus dem Chan, mein Soldier Girl & meine Vatos, und last

but not least an DICH

kEEP iT uP...

mAGiC...

2006-6-2 00:28
0
游客
登录 | 注册 方可回帖
返回