Log in

View Full Version : A challenge (or the many faces of ASProtect)


hobgoblin
September 14th, 2002, 08:07
Greetings,
I have a little challenge for those who have nothing do to this weekend. Go to xxx.eldos.org and download Timelyweb.
Try to unpack it.
I've tried but no success. I get to the point where I have located teh four usual redirected api's. Then after tracing a little bit, the program just stops working. I can't even get it to run. The program exit's after calling and executing the api findclose.
The program doesn't actually exit, but it hangs. Maybe the api findclose returns the wrong value. I don't know. Haven't quite figured it out yet. An interesting point is that in the call before it hangs, Alexevs name pops up a couple of times if you check the memory at certain locations while tracing the call.
Or maybe he is out with some new tricks?

Anyway, I'm going back to try some checking of using findfirstfilea and so on....

I just tought I mention this for some of the unpacking addicts here..

regards,
hobgoblin
PS: A friend told me that Revirgin doesn't work on this one either....

DakienDX
September 14th, 2002, 11:16
Hello everybody !

This one is really new. Maybe the protection's author starts reading the Intel Instruction Set Handbooks and tests the protection on serveral different computers before publishing it!

When I start the program, nothing happens and the program simply sits on the task list doing nothing.
Not that I'm running a debugger or something else on my computer, it simply doesn't work.

So what should I do next? Yes, restart the computer, load SoftICE and start to debug, since there is a bug in the protection else it would run.

The program starts and does nothing. I'm wondering why, enter SoftICE and find myself in the following (simplyfied) loop.
Code:

01 VarX = 6
02 RDTSC
03 If ((EAX Mod 8) == 4) then Goto 02
04 If ((EAX Mod 8) == 0) then Goto 02
05 AL = (EAX Mod 8)
06 VarY = 0
07 VarZ = 6
08 If (Table[VarY] == AL) then Goto 02
09 If (Table[VarY] != FFh) then Goto 12
10 Mov Table[VarY], AL
11 Goto 15
12 VarY = (VarY + 1)
13 VarZ = (VarZ - 1)
14 If (VarZ != 0) then Goto 08
15 VarX = (VarX - 1)
16 If (VarX != 0) then Goto 02

Table db FFh, FFh, FFh, FFh, FFh, FFh
I can't see what the use of this code should be. If it worked like the portection's author thought of, it would loop as long as the value returned by RDTSC doesn't return the values 1,2,3,5,6,7 in the bits 0-3 of EAX.

Here comes the problem. On my computer, a GenuineIntel P4, the RDTSC instruction returns always a value of 0 or 4 in the bits 0-3 of EAX.
So this pice of code will always end up in an infinite loop, in real and in protected mode, with debugger loaded or with no debugger loaded.

At this point the .code and .data sections are decrypted, but the IAT is still encrypted. So I have no way to even fix the problem as legal owner.

Nice protection. It prevents being used on usual 100% Intel computers. How imaginative.

hobgoblin
September 14th, 2002, 11:33
You got to be kiddin' me..

What you say is that this progam will never work as it is supposed to do if you have an Intel P4 on your machine?

Then this got to be an error made by the makers.

As you say: Nice protection..

Kayaker
September 15th, 2002, 08:14
Hi guys,

Just when you think there's no new twist... To start with, I had no problems loading or tracing the app on Win98SE, but I've got a P3. This RDTSC usage is very curious. There are a series of these commands used and they seem to access a couple of small jump-address tables, depending on their return value and the subsequent calculations. After a DIV, the edx remainder is used as an Index into a JMP NEAR [Index + table offset]. Since RDTSC returns a (relatively) random number, there seems to be a small element of randomization built into this routine.

The 1st RDTSC break occurs after the beginning of the .text section has been decrypted to recognizable Delphi, but before the IAT decryption routine starts. This app appears to be normal except for this extra call just before IAT decryption. The many faces indeed ;-)


After returning to high mem unpacking code after a VirtuallAlloc call that signals the end of the main decryption of the .text section, the code returns to the system through a FindClose call. FindClose returns to VirtualQuery, and via Kernel32 ORD_0001 more Asprotect code is called which contains the RDTSC routine. Some memory is allocated with GlobalAlloc then 'RDTSC' is used 4 times in unique code, then 40 more times within a LOOP. The LOOP is run 10 times and the results of the loop seems to vary slightly each time the app is run, sometimes calling GetTickCount, sometimes not.


In general the command is used like this:

Code:

18F1EE8 6A02 PUSH BYTE 0xh ; [ESP+8]
; Push DIV value, I've only seen x = 2, 3, 5, 8, and FFh

18F1EEA E80DFAFFFF CALL 18F18FC
18F18FC 52 PUSH EDX
18F18FD 0F31 RDTSC ; Read Time-Stamp Counter
; Read current value of processor’s time-stamp counter
; into EDX:EAX

18F18FF 31D2 XOR EDX, EDX ; don't need high-order 32 bits
18F1901 39542408 CMP [ESP+8], EDX ; don't want to div by zero
18F1905 7405 JZ 18F190C
18F1907 F7742408 DIV DWORD [ESP+8] ; divide time-stamp in eax
18F190B 92 XCHG EAX, EDX ; return remainder of DIV in eax
18F190C 5A POP EDX
18F190D C20400 RET 4

The RET 4 seems to always be to one of three instructions.

CMP EAX, BYTE +4
or
JMP NEAR [EAX*4+18F1EF6]
or
JMP NEAR [EAX*4+18F1F0C]

The returned EAX is a single digit Index value. There seems to be a general pattern in the sequence of
PUSH BYTE 0xh
..
RDTSC

calls, but it also looks like there can be some variability as well. The value pushed will be the divisor used in the DIV statement, which in turn will affect the remainder in EDX which is used as the next jump table Index value, and so on through all the RDTSC calls.

------------------------------

The whole routine begins with a call to GlobalAlloc just before the first RDTSC call. The allocated memory is used for decrypting something, but I've no idea what really, this is only part of a larger routine.

Code:

12 18E5198 FF25F0818F01 JMP [ KERNEL32 - GlobalAlloc ]
...
22 18F2069 E87AFEFFFF CALL 18F1EE8

23 18F1EE8 6A02 PUSH BYTE +2
; begins with 2 as the divisor
24 18F1EEA E80DFAFFFF CALL 18F18FC
25 18F18FC 52 PUSH EDX
26 18F18FD 0F31 RDTSC
27 18F18FF 31D2 XOR EDX, EDX
28 18F1901 39542408 CMP [ESP+8], EDX
29 18F1905 7405 JZ 18F190C
30 18F1907 F7742408 DIV DWORD [ESP+8]
31 18F190B 92 XCHG EAX, EDX
32 18F190C 5A POP EDX
33 18F190D C20400 RET 4

34 18F1EEF FF2485F61E8F01 JMP NEAR [EAX*4+18F1EF6]


The several JMP NEAR [EAX*4+18F1EF6] instructions are interesting because the absolute address jumped to can vary depending on the results of the RDTSC div. Each time you run the app the pattern can be slightly different it seems. This jump leads to further RDTSC calls which push either BYTE +5 or BYTE +3 to [ESP+8] in the DIV statement.

--------------------------

When JMP NEAR [EAX*4+ 18F1F0C] is used, it's always to a loop which begins with PUSH BYTE +8 and leads back to the JMP NEAR [EAX*4+ 18F1EF6] statement which can branch as just mentioned between +5 and +3.

Code:

18F1F05 FF24850C1F8F01 JMP NEAR [EAX*4+18F1F0C]
18F1F20 C3 RET
18F206E E2F2 LOOP 18F2062

; total loop is 105 lines
18F2062 E8C9F8FFFF CALL 18F1930
18F1930 6A08 PUSH BYTE +8
..
18F18FD 0F31 RDTSC
..
18F1907 F7742408 DIV DWORD [ESP+8]
18F190B 92 XCHG EAX, EDX
..
18F1937 83F804 CMP EAX, BYTE +4
18F193A 0F84F0FFFFFF JZ NEAR 18F1930
18F1940 C3 RET
.
.
18F1EE8 6A02 PUSH BYTE +2
..
18F18FD 0F31 RDTSC
..
18F1907 F7742408 DIV DWORD [ESP+8]
18F190B 92 XCHG EAX, EDX
..
18F1EEF FF2485F61E8F01 JMP NEAR [EAX*4+18F1EF6]

...to further RDTSC calls which use either
PUSH BYTE +3 or PUSH BYTE +5




I haven't got the foggiest what this code is supposed to be accomplishing in the grand scheme of things Does any of this fit in with what you were seeing DakienDX? I haven't checked how the bit values returned with RDTSC might affect the code flow and whether an endless loop could be created. What could be so special about P4 and RDTSC?

/endsession

Kayaker

Snatch
September 15th, 2002, 09:53
Upon further analysis this protection is driving me crazy. This is very clever. I will have to study it a lot longer. DakienDX and Kayaker your comments were helpful but this ones going to take a bit more work. Wonder who made this protection or if we can find info on it anywhere?

Snatch

DakienDX
September 15th, 2002, 11:01
Hello Kayaker !

We're talking about the same piece of (bad) code.

I've only seen the division by 8 and taking the result, but I couldn't get further on my CPU.

The RDTSC instruction reads the number of CPU clock cycles since the last RESET. It's immune to SoftICE freezing Windows, not like the GetTickCount function. The value should be "random", but Intel says the instruction takes 20-24 CPU clock cycles. This way they maybe let themselves a backdoor open for always having the bits 0 and 1 cleared in EAX after executing RDTSC on a P4.

I can't tell about any small jump tables, I haven't seen them. It just kept me in the endless loop and when I gave the loop the values it expected (1,2,3,5,6,7) I was taken to another loop, also RDTSC, but different this time. I think it could be your third piece of code, since it was a "Cmp EAX, 4; If EQ goto ??? else Ret" loop. After the Ret, EAX was compared with 0 and then again I was in an infinite loop.

After I had passed this loop, I tried to run the program, but I got a BSOD. (even with "FAULTS ON"

I remember having seen the GetTickCount call right below the RDTSC code, but it was never called on my computer.

I think the tables generated are only used to confuse the reverser. In the first piece of code all jumps would be executed, only the order would be different each time. They can't be sure to get always the same values out of RDTSC and they can't be sure that the values come in the same order every time.

But we had this kind of (bad) protection already. When switching form the 486 to the Pentium, Intel enhanced the instruction prefech queue so that it would detect any memory changes made after filling the queue. This was a nice "feature" used by some protections. It was impossible (yes, completely) to trace the code. But now all protections using this feature didn't run any more and it was impossible (yes, also completely) to run the programs.

But I don't think the P4 is too new that anybody has ever tested a program on it. I have even two of them.

foxthree
September 15th, 2002, 11:39
Hi Kayaker/Dakien:

Nice this one The best way to defeat a cracker is to not allow him to run the code at all

Anyways, just to add a small point to Dakien, in fact to allow refreshing of the prefetch queue, one needs to call FlushInstructionCache(). I hope most loaders/patchers are making use of this otherwise they may not work on older CPUs. Also, would this by any chance be Alexey's ways of rebasing the OEP to "totally random". I mean the current rebased OEP has been completely analzyed by +Splaj and I have my own "home-brewn" version of analyzing the rebased OEP.

Could this be Alexey's attempt at "true" OEP rebasing ? Just a thought ...

Signed,
-- FoxThree

PS: Thanks to hobglobin for this "funny" target

+SplAj
September 15th, 2002, 11:49
Dak

I have just d/l some targets ready for tonite

But looking at the d/l infos maybe Eldos already know of your predicament ?

:-

Version 3.30 (build 143). released 09.10.2002, 1381 Kb
Download.com:
EldoS site: EldoS TimelyWeb
EldoS mirror site: EldoS TimelyWeb


Version 3.30 (build 141). Use it if build 143 fails to load.
EldoS site: EldoS TimelyWeb
Version 3.30 (build 138). Use it if build 143 fails to load.
EldoS site: EldoS TimelyWeb

maybe 'Fails to load' == P4 chip ?

evaluator
September 15th, 2002, 13:18
I think:
maybe this is some TEST-version of asSpr.
here I detect new(for asspr) tricks.

1. garbage bytes in before&after IAT
2. garbage bytes between DLL-thunk blocks
3. strip 14 bytes of OEP to asspr-memblock
4. new kind of IAT-redirector code (RV & imprec sux)

Maybe new crackers joined to ASS?

About RDTSC.
I have P3 CopperMine600 so have not any probs for run.

DakienDX
September 15th, 2002, 14:19
Hello foxthree !

"prefetch queue" is not the same as "prefetch queue".
I know that the two strings are identical, but we're talking about two completely different things.


Hi +SplAj !

Thanks for the tip. I didn't read it because it was only two lines below the donload link.
Build 141 runs on my P4 and I've unpacked it successful.
I noticed that the jump to the OEP is always at a different location in memory, while the ASProtect base address is the same every time.
I haven't tried Build 138 yet. This could be the "normal" version, Build 141 the "hard" version and Build 143 the "anti-P4" version.


Hi evaluator !

ImpREC works fine for Build 141. I had only one strange entry with the following code:
Code:

Push EDX
Push C0xxxxxx
Ret
This one leads me to WideCharToMultiByte. I've no idea how or why this works and why the import table points to this code. Perhaps it's really a test version of ASProtect.

OEP of Build 141 is at 00621558h if it helps anybody. If the theory is correct, it should be there as well in Builds 138 and 143.

SpeKKeL
September 15th, 2002, 14:43
I didn't look at the targets here mentioned but i had several nasty
experiences with latetest imprec 1.4.2+ (aspr/telock).
Sometimes imprec refuses to: change an api, invalidate, or make use of a plugin.
Something to do with seh's ??
Maybe it's only on my sys, but imprec 1.3 seems to work still the best.
(not all updates are an improvement)
btw nobody did play the game ??(see my other thread)

Cheers,

SpeKK

DakienDX
September 15th, 2002, 15:33
Hello everybody !

I just want to update my adoptions.

Build 138, 141 and 143 are different builds, not the same ones with different ASProtect options. Therefore it's OEPs are different.

The function WideCharToMultiByte is not called when executing the application, so I don't know if the strange call would crash or if it would work.
It looks like the procedure is hooked by some driver, but GetProcAddress returns the original KERNEL32.dll API.

evaluator
September 15th, 2002, 16:04
hobgoblin!

my unpacked EXE normally runs.
When crashes your? Soon after start or after 13 min~:0?

Hi Spekk!

What game about you?
BTW, download this target (v3.3.0.143) & play with it

hobgoblin
September 15th, 2002, 17:11
Hi guys,
Seems you have sorted it out.
I just can't do anything right now. My main machine collapsed earlier today, I think the motherboard went straight to hell.
So now I'm humping away on an old laptop, but can't do any research. I'll guess I have to go out and buy myself a new one tomorrow.
I'll get back in the race as soon I have a new machine.

hobgoblin

DakienDX
September 15th, 2002, 18:23
Hello hobgoblin !

Looks like we've similar problems. You can't execute the program since your motherboard is broken and I can't execute it because I've a P4.

If you decide to get a new CPU too, choose it wisely, you know now what can happen if you're using a common CPU.


Hello everybody !

I've played around a bit with Build 141 and found out that the redirected API leads to WinExec really.
I checked the ASProtect code and it really executes GetProcAddress(WinExec) and saves the address in the import table.

I found some references to the call in the disassembly. Eight parameters are passed to the call. WideCharToMultiByte takes eight parameters, WinExec only two.

Can somebody please check this on your computer for Build 141 or Build 143?

hobgoblin
September 15th, 2002, 18:38
Hi guys,
Can't stay away for too long can I?

DakienDX:
You bet I'll get a nice one this time. Planning on getting the fastest Intel there is.

I have not checked out what you described, but I have successfully unpacked it and rebuilded it on my other machine.
Nothing new was revealed to me during the process. I used a loader to locate the oep and the dips (yeah, I know: lazy son of a b...). I located the usual 4 redirected api's, and had no problem using Revirgin to rebuild the imports. It resolved all but 10 calls. And these 10 were the usual ones. I didn't jump the dips or anything. All usual business. And it ran nicely without further work. (Didn't run it for extended time though).
Just wanted to let you guys know...
BTW: I worked on build 141.

regards,
hobgoblin

A question: I've been searching all afternoon for a proggie called Superbpm for NT. And I only find Superbpm. If someone have seen where it is lately,could you please notify me by mail or something? I know it exists, because I have it on my other computer.
TIA.

evaluator
September 15th, 2002, 18:44
what thunk you want for check?
write addr for v143.

Generally you should watch for Imp-names when they are decypted
& you will be 99% sure.

DakienDX
September 15th, 2002, 19:31
Hi evaluator !

I don't have any offsets for 143, since it doesn't execute on my computer. (P4 -> infinite loop)

I checked 141 (which runs on my computer) and found one import which is somehow completely wrong.

In 141 it's at address 0062C354h. It's the import between WriteFile and WaitForSingleObject.

It must be WideCharToMultiByte, but when loading the imports, ASProtect executes GetProcAddress("WinExec". GetProcAddress returns an address in the C0xxxxxxh address space, runs through the normal redirecting code and puts the address in the import table. Here's the code from the import table:
Code:

; Possibility #1
Push EDX
Push C0xxxxxx
Ret

; Possibility #2
Push EDX
Jmp C0xxxxxx
C0xxxxxxh is the (value+1) returned by GetProcAddress for WinExec.
But the function should be WideCharToMultiByte and not WinExec.
(I still don't know why I get C0xxxxxxh instead of KERNEL32 address space)

So I was wondering if anybody can verify that it runs the same on his computer.
I know we're no ASProtect's bug checking team. (maybe we are )

evaluator
September 15th, 2002, 20:08
ok, now write peace of rv.txt with few imports
before & after

TaGaDaPaF
September 15th, 2002, 20:36
soz but, what's the problem with build 141 ?
my dump working find, and it can export url (writefile)

DakienDX
September 15th, 2002, 21:02
Hello evaluator !

I don't know why this should help.

The API isn't resolved and the address the import table points to is different every time you run the program.

I know what the right API is, but I don't understand why ASProtect loads the wrong API.

And TaGaDaPaF, I think I just told you five minutes ago to read to FAQ. Then you would have read the thread before posting and would have posted something which fits the topic or wouldn't have posted anything at all.

+SplAj
September 18th, 2002, 12:31
*new* ASPR v1.3x ?
===================

Finally I had a chance to play with Alexey's new aspr release
on that lame target from Eld*s site :-

1st thing to note for us poor guys is the demise of POPAD + JMP EAX (61 FF E0) as the
clue to getting to OEiP.

instead we have something like this :-

0167:013A4EA4 E800000000 CALL 013A4EA9
0167:013A4EA9 5D POP EBP
0167:013A4EAA 81EDBD6F4900 SUB EBP,00496FBD
0167:013A4EB0 8D8DD16F4900 LEA ECX,[EBP+00496FD1]
0167:013A4EB6 03CB ADD ECX,EBX
0167:013A4EB8 894101 MOV [ECX+01],EAX
0167:013A4EBB EB00 JMP 013A4EBD
0167:013A4EBD 55 PUSH EBP <-part of Original EXE !!!
0167:013A4EBE 8BEC MOV EBP,ESP
0167:013A4EC0 83C4F4 ADD ESP,-0C
0167:013A4EC3 53 PUSH EBX
0167:013A4EC4 56 PUSH ESI
0167:013A4EC5 57 PUSH EDI
0167:013A4EC6 B838126200 MOV EAX,00621238
0167:013A4ECB 68DE196200 PUSH 006219DE <- OEiP ???
0167:013A4ED0 C3 RET

Note that SEVERAL 1st bits of codse are here also !!! (thanks Evaluator)

Also note that the 'double-dipping' scheme is still present .... so extra care to be taken
Next is the BEAUTIFULLY coded *new* *rebased* and *randomized* IAT re-director
enc/decryption to the real re-director code. This I have to say is a great
programming achievement from Alexey - well I have to say that cos i'm gonna show
you how to bust it

The code is an attempt to stop the IAT tracer from RV/ImpREC......
For RV's Tsehp tracer, RV managed to find a lot of API, but
unfortunately it does NOT have a 'cut-thunk' feature as the IAT is ONE LONG
muther fucker without any 00000000 spaces to define one dll from the next.
Imprec has this feature but unfortunately COMPLETELY FAILS to trace any API at
all - for me ?

So the first solution is to wait months for Tsehp and G-Rom to update their
nice toolz for us (coz they are buzy) .... er no, we do it ourselves with a
plugin

Unfortunately the plugin system is lacking the parameters to make a real
'tracer' out of it, but I managed to fix this IAT and here is the procedure :-

1_ run target to OEiP (G <OEiP_address> after SuperBPM/NtDump)
2_ hold with eb fe
3_ start Imprec
4_ resolve the imports (manually find the IT ????)
5_ see only ONE long import !!!
6_ CUT the crap thunks out
eg:-
FThunk: 0022C1F0 NbFunc: 00000400
0 0022C1F0 ? 0000 95298DE7 <-CUT HERE
0 0022C1F4 ? 0000 00F9925C <-fake redirectors to be de-crypted
0 0022C1F8 ? 0000 00F99368 to real re-director.....
0 0022C1FC ? 0000 00F99384
0 0022C200 ? 0000 00F993A0
0 0022C204 ? 0000 00F993C0
0 0022C208 ? 0000 00F993D0
0 0022C20C ? 0000 00F99414
0 0022C210 ? 0000 00F99454
0 0022C214 ? 0000 00F99494
0 0022C218 ? 0000 00F994B0
0 0022C21C ? 0000 00F994CC
0 0022C220 ? 0000 00F994F4
0 0022C224 ? 0000 00F99514
0 0022C228 ? 0000 00F99534
0 0022C22C ? 0000 00F99570
0 0022C230 ? 0000 00F995B0
0 0022C234 ? 0000 00F995EC
0 0022C238 ? 0000 00F9960C
0 0022C23C ? 0000 00F9962C
0 0022C240 ? 0000 00F99674
0 0022C244 ? 0000 00F80F18
0 0022C248 ? 0000 00F81388
0 0022C24C ? 0000 00F9969C
0 0022C250 ? 0000 00F996BC
0 0022C254 ? 0000 00F996DC
0 0022C258 ? 0000 00F813F8
0 0022C25C ? 0000 00F996F8
0 0022C260 ? 0000 00F99718
0 0022C264 ? 0000 00F99758
0 0022C268 ? 0000 00F99794
0 0022C26C ? 0000 00F997D4
0 0022C270 ? 0000 00F99808
0 0022C274 ? 0000 00F99848
0 0022C278 ? 0000 00F99884
0 0022C27C ? 0000 00F998A4
0 0022C280 ? 0000 00F998C8
0 0022C284 ? 0000 00F998E8
0 0022C288 ? 0000 00F99928
0 0022C28C ? 0000 00F99948
0 0022C290 ? 0000 00F9996C
0 0022C294 ? 0000 00F9998C
0 0022C298 ? 0000 00F999AC
0 0022C29C ? 0000 00F999D4
0 0022C2A0 ? 0000 00F999F4
0 0022C2A4 ? 0000 00F99A18
0 0022C2A8 ? 0000 F80AD623 <-CUT HERE!!!
1 0022C2AC user32.dll 011C GetKeyboardType
1 0022C2B0 user32.dll 01B0 LoadStringA
1 0022C2B4 user32.dll 01C4 MessageBoxA
1 0022C2B8 user32.dll 0026 CharNextA
0 0022C2BC ? 0000 33A0E371 <-CUT HERE!!!
1 0022C2C0 advapi32.dll 01AD RegQueryValueExA
1 0022C2C4 advapi32.dll 01A3 RegOpenKeyExA
1 0022C2C8 advapi32.dll 018A RegCloseKey
0 0022C2CC ? 0000 0151B35D <-CUT HERE!!!
1 0022C2D0 oleaut32.dll 0093 VariantChangeTypeEx
1 0022C2D4 oleaut32.dll 000B VariantCopyInd
1 0022C2D8 oleaut32.dll 0009 VariantClear
1 0022C2DC oleaut32.dll 0007 SysStringLen
1 0022C2E0 oleaut32.dll 0006 SysFreeString
1 0022C2E4 oleaut32.dll 0005 SysReAllocStringLen
1 0022C2E8 oleaut32.dll 0004 SysAllocStringLen
0 0022C2EC ? 0000 98DE7654 <-CUT HERE!!!
0 0022C2F0 ? 0000 00F99A40
0 0022C2F4 ? 0000 00F99A64
0 0022C2F8 ? 0000 00F99AA4
0 0022C2FC ? 0000 00F81388
0 0022C300 ? 0000 00F99ACC
0 0022C304 ? 0000 277D6D43 <-CUT HERE!!!... etc etc etc for all imports.
etc etc

save your 'tree.txt'

8_ Now using my alpha release of'aspr13.dll' plugin select the fake re-directed calls. Imprec will say FAILED
but SAVE and immediately RELOAD the 'tree.txt' and select them again and select 'Trace Level1 (Disasm)'
and voila,API calls appear..SAVE the tree.txt....

You still have to figure out the GetVersion/GetCommandLine/LoadResource etc etc API manually.
Rebuild the IAT in the usual way and your done.

I enclosed some GIF piccy's + plugin dll to explain the procedure.........I hope that helps the blind ones !

Greetz to all, esp. Alexey. Nice new aspr work for a 'lazy guy' uh

Spl/\j
[c]2002

+SplAj
September 18th, 2002, 14:35
EldoS TimelyWeb - Version 3.3.0.144 - Released 15 September 2002
----------------------------------------------------------


What's new:

[ Legend: ]
[ + Added feature ]
[ * Improved/changed feature ]
[ - Bug fixed (we hope) ]

---
15 September 2002
v.3.3.0.144 Minor update
- Alexey fixed a problem with running on Pentium 4 processors.

SpeKKeL
September 18th, 2002, 20:29
Hajo,

Yep i did this target without to much trouble, using imprec 1.3
and my own plugin for those few unresolved(resolved all).
Yes imprec can't find iat and you must cut a loooot of thuncks..

Sjit i was just writing about this pre-oep thing while i was reading some earlier posts and saw it's allready written..
That's why i had to push another number in eax...!!

Nice playing here,

Greeets

SpeKK

hobgoblin
September 18th, 2002, 21:48
Greetings +Splaj,
Nice of you to come up with some info to work on. I have one question for you: How did you find the code where the first 14 bytes of the real program is located? Together with the OEP?
It changes location every time you load the program, so I guess it used getlocaltime or some other related api to somehow randomize where the final code before jumping to the oep is going to be located?

regards,
hobgoblin

Hwoarang
September 18th, 2002, 23:55
Splaj, here is a url for you:

http://www.onefog.com/

I had to modify iat handler, since the Splaj plug-in didnt worked..

evaluator
September 19th, 2002, 08:21
hello, splaj!

I wrote little tut for you, how to make little graphic files.
Tools used: IRFANVIEW

Load your GIFs in IRFANVIEW;
Decrease Color Depth > 8 color;
Save as PNG for ZIP (solved 37000 bytes)
OR save as BMP with SOLID-archive compression! (solved 45000 bytes)

EnjoE!

+SplAj
September 19th, 2002, 08:40
Hi Eval
=====


Actually i did think about 'protecting' my little dll (8k un-optimized) with Titty III .......but then it would have been 800k

Thanks go to MS Paint for the shit gif compression all complaints about bloatware to Bill please as I don't care....


Hi SpeKK
======

I tried your GWWW API plugin dll and it works a treat on Win98SE, but not in Win2K ?
I almost got round to poking your nice code into my dll as well.....but thats for the next Beta plugin, cos Alexey will make some changes

I never tried 'old' version of Imprec ! thanks for the tip.


Hi Hobgob
=======

Please re-read the GetSystemTime infos on rebase OEiP....same scheme different 'signature bytes'....HINT HINT

Happy reversing to all.


Spl/\j

hobgoblin
September 21st, 2002, 07:48
Hi there everyone,
Well, I managed to unpack Timelyweb into a working copy. After reading +Splaj's latest reply I also managed to find a couple of ways to find the oep quite easily. The dumping went eay, so did changing the oep value 14 bytes backwards, and then add the 14 bytes the program loads in a higher memory location. To rebuild the import table was more work than I anticipated to begin with.
After making the program loop at oep, I tried Revirgin to find the import. It worked well after entering the correct iat address and size. It also listed all the false api calls. But since there is no way (as far as I know) to cut thunks when you run Revirgin, I had to switch to Imprec. Then I had to do as +splaj explained. But Imprec came up with less resolved api calls than revirgin. I ended up with 30 calls that had to be manually typed in. It was easy since I already knew from Revirgin what they were supposed to be. And of course I had to change the "old" redirected api calls (ten calls).
Nice target. Nice to see and learn something new in Asprotect.
But I keep thinking: maybe there is a way to change how the program decrypts and stores iat values during runtime (during unpacking), so all these false api calls were removed and not loaded into memory? And then Revirgin could catch all but the correct api calls?
Or maybe the author of Revirgin could add a cut thunk feature in the program? it would sure be helpful.
Thanks for the help......

regards,
hobgoblin

nikolatesla20
September 30th, 2002, 20:26
You can do a form of cutting with RV. In fact, it was this very "protection" that I have always been prepared for, because I've run into it before, in small weird ways.

This is actually something I always did myself, with RV, because sometimes it wouldn't get the IAT length correct, and so I would just throw in a nice large number. Because of that you end up with a whole bunch of empties on the end of the IAT.

All you gotta do is tell RV to save the IAT. you know, save as text.
Now open it up in notepad and cut out the ones you don't want, change the order ( the first column) , and save it. You could probably even use Excel to do this quicker. ( the reordering of the first column of numbers )

Go back to RV and open up the IAT text and now you can export you shiny new IAT table.

I use this technique at lot as well to replace incorrect IAT calls, instead of typing the memory address into RV and pressing "Resolve" again, ( which can be dangerous, it can lock up my win98 computer sometimes ), I simply leave the address at whatever it was, and just change the DLL name and the function name in the resolved.txt file. Then I bring the text file back in, and create my IAT. The names are the only important part anyhow.

-nt20

hobgoblin
October 1st, 2002, 15:04
Thanks for the idea.:-)
I should have thought about this one, as I have been working with Excell for years...
Nice.

hobgoblin

evaluator
October 1st, 2002, 21:58
while using excel..
in debugger clear-up IAT-space before IAT will decripted & enjoE

hobgoblin
October 2nd, 2002, 06:24
I'm not sure I understand how you do that. Can you please explain how you do it?

regards,
hobgoblin

evaluator
October 2nd, 2002, 08:14
before asspr will write something in IAT,
fill IAT-section with 00h in debuger's data window(as it was clear in previous versions).
That is clear garbage bytes, not used by protection.

hobgoblin
October 2nd, 2002, 17:58
Nice.
It works like a charm...
Thanks for the tip.
Actually I want to say thank you for all the information you post on this board. I always find it helpful.

Regards,
hobgoblin

foxthree
October 6th, 2002, 19:17
Hello Folks:

Joined the party late but the beauty is that fun part is always there... Anywayz, all the greats have seen and forgotten this by now ... +SplAj guru, Eval, SpeKKel.

After tracing a while, I did find a couple of ways (apart from the nice GetSystemTime hook) to find the OeIP in like 2 secs... But the fun part is the IAT... Maybe +Tsehp will code Cut Thunk in future release of RV. I personally like RV 'coz it resolves APIs much better Or may be someone out there will write and release an ImpRECT Tree -> RV IT.txt converter ... Being just too lazy

Yep, unpaxed and got it running.... Indeed phun...

See ya around,

Signed,
-- FoxThree

hobgoblin
October 6th, 2002, 19:49
Hi Foxthree,
Want to share your newfound ways of finding the OEP with us, or is it a secret?


hobgoblin

GlObAl
October 6th, 2002, 21:26
hello hobgoblin and all,
its not a secret to find the oep...
in every new version it get easyer and easyer...

1. Start you target.exe

2. Break everywhere you want for example but a bpx on enablewindow and open the about or something like that.

3. After breaking type the following in sice...
s 0 l ffffffff C3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
and Softice will show you an address thake this address and use it with the U commant for example u address than scroll up 1 line and you will see the oep...

push OEP
ret
nop
nop

thats it, quit easy...

best regards...

P.S.: Inlinpatching still possible

hobgoblin
October 6th, 2002, 22:20
Right.
I'm using something similar. I usually bpx on getversion, do a search for the iat decryption routine, and when I'm done getting the info there, I continue with a bpx getversion. After it breaks, I do a search for 03,CB,89,41,01,EB,00,55
Softice gives back an address, and when I do a U <address>, I end up in the same place as you do. The only negative with my approach is that I have to restart the program, and go via Getsystemtime to get to the same code. Hmmm, think I will try your method.
What I'm curious about is whether there is an "elegant" way of using the API's to find out what the OEP is?
hobgoblin

evaluator
October 7th, 2002, 07:46
Hello!

IF in prog used bytes ripping from OEP, then

PUSH [address]
RET

is not OEP, but place where continues execution after ripped OEP.
So you firstly must restore this ripped bytes before this place
& then mark start of restored byte as OEP.

IF NOT used ripping, that is OEP.

So now we need to break on that ripped bytes inside asspr memory.
either debug whole shit.

Either use old method of stack checking.
Most "correct" protectors restores startup stack(ESP) value before OEP.
So checking this ESP is not bad idea yet

(for example, DAEMON in his beta protector not restores ESP. That is trick, not mistake.)

foxthree
October 7th, 2002, 09:56
Hello all:

Hmm it seems that many ppl. are interested in finding "elegant" ways of finding ASPR OEP. There are really phun ways of finding OEP with ASPR... which is what I like

What GLobal wrote is correct and what Hob writes is correct too. However, after relying on signatures for finding OEP (and I still do), I try to find "universal" ways of finding OEP (if possible without sigs).

Remember, the trick here is that protectors can only "incrementally" change their code not "drastically". For ASPR, its strength is its weakness I'm referring to the SEH stuff ....

Anyways, let's not make life easier for Alexey our friend I'm sure gurus like +SplAj and Eval have already a couple of nice tricks themselves ...

Eval: I think by ripping part of the OEP code Alexey intends to send the KanXue Studio Loader out of the window and he has succeeded in that as the stacks are unbalanced now ... but we can rectify that can't we ?

Signed,
-- FoxThree