Log in

View Full Version : New Securom - sintf*.dll files


ramon
April 4th, 2002, 16:38
Hi all,

Anyone had played with new version of Securom tha uses sintfnt.dll, sintf16.dll and sintf32.dll


I'm in war with it, any suggestions? or tutorials available?

Bye
Ramon

DakienDX
April 4th, 2002, 16:58
Hello ramon !

By entering "Securom" in the search function you would have found some threads dealing with it.

If you've a working CD it's really no problem dealing with it. You need just a dump of the game's ".code" section. The program uses one call for all imports, so you've to program some code by your own which "gets" (I won't tell how, else there wouldn't be any fun ) the imported function's addresses out of the call and replaces the addresses in the dumped ".code" section with the right calls.

Kilby
April 5th, 2002, 11:27
The following changes where made to securom.

The offset to the oep moved (along with the jmp eax)

Some of the code moved around in the api decryptor moved.

They screwed with the vsize of a section so as some of the dumps are huge (Monsters Inc Swedish Version came out at 115 meg).

They changed the .dll name

Nothing major has changed at all.

Thats about it really, .

R!scs tut still holds true for ALL the important parts.

Now all you have to do is work out how spme bits of the api decryptor works

Regards,

Kilby...

ramon
April 7th, 2002, 19:36
Yeap, almost all trics from r!sk's tuts continue valid, but my target gets me crazy about fixing the IAT table. When you make a

call DWORD PTR[securom] you get one valid pointer

if you do like r!sk

jmp DWORD PTR[securom] you got diferent address (invalid) and very FF 15 ?? ?? ?? patterns do AV errors in securom functions

I can't figure out whats going on!!! maybe securom do checks over stack, routing our jmp. But if I change the the small asm code to call DWORD PTR[securom] in some cases the function never returns.

I know the real OEP ), but IAT arrrrrgggggggggg

Suggestions??

Thankz
Ramon

DakienDX
April 7th, 2002, 19:37
Hello ramon !

I don't know how r!sc did it, but I'm sure he didn't do it with just a "Jmp DWord Ptr [Securom]". He must have placed a "Push ???" right in front of it, where "???" holds the address from which the (fake) call is made.
If you do a "Call", the return address in placed on the stack, if you do a "Jmp", no address is placed on the stack. Therefore you must take care that this address is placed there before the "Jmp".

Remember that you must also patch the "[Securom]" function so that it will return to your code with the API address in EAX instead of returning to the address in EAX, the API.

ramon
April 7th, 2002, 22:54
Hi

Yes I'm paching securom function in runtime, then I can do a loop over all .text section to find desired pattern of bytes, when found jmp to securom_funtion, but before I fake it with a push on stack of the address where I found the pattern. At that time I change the end of securom_function where it jumps to the right address
changing from "jmp eax" to "jmp ebx", why? This function doesn't use ebx, then before making the jump to securom_function I make ebx equal to the address in our little asm code just after the jump to securom_function.

Then we can think that all should work as we expected, but NO (
The greater part of patterns founded create errors in the securom_function, weird!?!

As I refer before, I beleave that securom_function verifies if was by call or by jmp, is that possible?

Sorry if my english is complicated.

Ramon

blackcheck
April 8th, 2002, 07:13
sometimes the jump eax inside the call dword ptr returns
securom address instead of the real api,that's all.

Kilby
April 8th, 2002, 09:28
Ok regarding the resolving of the api functions.

This is fairly easy, but it's obvious that r!sc was only out to make a working dump of outcast and not to document securom.

Some api calls pass through the resolver up to three times, some may pass through more times than that but I got the idea after a while

What happens in those cases is that the jmp eax at the end of the resolver ends up pointing into a table containing the address of the resolver.

Another part mentioned by r!sc is that for some reason the resolver seems to give errors on some api addresses.

This is indeed the case, this is because the resolver counts the number of apis being called, and seems to screw itself up if too many consecuitive calls are made to the routine

To fix this 2 instructions (4 bytes) need to be patched, and they are obvious in an ida listing.

The route you are taking for the register value you are using is almost correct.

I'm not saying too much otherwise my dumper will suddenly need rewritten.

To completely own the resolver, you must pass 2 appropiate values and patch 5 bytes.

Regards,

Kilby...

DakienDX
April 8th, 2002, 16:05
Hello ramon !

I see r!sc did it the same way as I did it.

At the end of the "[Securom]" function there is a "Jmp EAX", where EAX holds the pointer to the API to jump to. So the function would just execute the API and we wouldn't know the API address. Because of this you need to patch the function call to give you the API.

You can't use a "Call DWord Ptr [Securom]", since the procedure would try to find the correct API for your call address, not for the right call address.

It's impossible for the "[Securom]" function to handle a "Jmp DWord Ptr [Securom]", since it wouldn't know from which address it was called and where it should return after the API is executed.

(I'd planned to anwer different, but I don't want to harm Kilby's dumper. )

ramon
April 8th, 2002, 23:24
Hi Kilby and DakienDX

Kilby's tips make my hard work a little more easy
I found it!!! the last things I need to do is find the rigth IAT table
because the unpacked app only run in the system were I unpacked it, ie, if unpacked in Win200 doesn't run in 9X and vice versa. You know why! .

But I know how to do that. This step seems easy, tomorrow I will tell you if i beat that bitch

Thankz guys
Ramon

ramon
April 9th, 2002, 09:52
Be Cool
Ramon

Kilby
April 9th, 2002, 10:10
Hehe, glad to see that my hints where of some help.

Theres almost always two import tables in a securom .exe.

If you want to look at two wierd securom examples I suggest :-

Fortress Europe which is written in VB

Sub Command (from EA), which always ends up with me having to adjust the imports by hand and it has some wierd sections attached to it.

The funny thing is that I can only get the tables to work properly from 98 (the 98 dumps run inder 2K & XP), but if I dump from 2K then they only work on 2K systems.

As I don't have (or even wish to have) a 2K system at home, I don't have time in work to explore the problem.

Anyway good luck with any further securom exploration.

Kilby...

Gadix
April 12th, 2002, 09:31
Hi SecuCRACKERS

r!sc tutorial is 80-90% valid... r!sc talks about "bad calls", this is due Securom do
a randoms CRC-checks in API-WRAPPER routine and he doesn't patch CRC comparison. The
comparison has the following form: (scroll in Securom API routine)

MOV ECX,[EDX]
CMP ECX,[EAX]
JZ GOOD_CRC

If you change JZ to JMP you can patch peacefully the JMP EAX to your fixer-routine. You can
get more info in my securom tutorial(in spanish) at h**t://gamescrk.cjb.net

New versions also have a time comparision (with WINMM_TimeGetTime) to check the number of
times that securom routine is called in certain time to a
void IAT-APIrebuilders (& my UnSecurom :d )

Gadix

[NtSC]
April 12th, 2002, 16:14
that Time compare Routine is just defeated with 3 Nops and you can go on without any Problems :-)

For some Games u could..
Breakpoint on EnterCriticalSection

if next Instruction is an mov..
and next instruction to the mov is an add e??,01
just erase that and you can decrypt the whole bunch of collected adresses.

<just kindly figured on Zax - The Alien Hunter...>

Cheers Gadix,long time no see :>

acoder
November 23rd, 2003, 11:13
(heya NtSC )

About the time thing, I think its this:
MOV DWORD PTR SS:[EBP-2C],0
CMP DWORD PTR DS:[580EDC],0 <-- check for some flag?
JNZ SHORT 004C2079
CALL DWORD PTR DS:[596BBC] ; WINMM.timeGetTime
MOV DWORD PTR DS:[580EDC],EAX
JMP 004C2198
CALL DWORD PTR DS:[596BBC] ; WINMM.timeGetTime
MOV DWORD PTR SS:[EBP-30],EAX
MOV EAX,DWORD PTR SS:[EBP-30]
SUB EAX,DWORD PTR DS:[580EDC]
CMP EAX,0EA60
JBE 004C2198 <-- good boy

maybe someone knows whats the big numbers (?) used
after a check...like this:
CMP DWORD PTR DS:[50B1A0],0 <-- another flag
JE SHORT 004C20AE
push offset "72311C5AEBA713BD58..."

cya

naides
November 23rd, 2003, 11:42
Quote:
[Originally Posted by acoder](heya NtSC )

About the time thing, I think its this:
MOV DWORD PTR SS:[EBP-2C],0
CMP DWORD PTR DS:[580EDC],0 <-- check for some flag?
JNZ SHORT 004C2079
CALL DWORD PTR DS:[596BBC] ; WINMM.timeGetTime
MOV DWORD PTR DS:[580EDC],EAX
JMP 004C2198
CALL DWORD PTR DS:[596BBC] ; WINMM.timeGetTime
MOV DWORD PTR SS:[EBP-30],EAX
MOV EAX,DWORD PTR SS:[EBP-30]
SUB EAX,DWORD PTR DS:[580EDC]
CMP EAX,0EA60
JBE 004C2198 <-- good boy

maybe someone knows whats the big numbers (?) used
after a check...like this:
CMP DWORD PTR DS:[50B1A0],0 <-- another flag
JE SHORT 004C20AE
push offset "72311C5AEBA713BD58..."

cya



Typically,
DWORD PTR DS:[580EDC] Refers to a 'global' variable, which is located in the data segment ( DS: ) and is 'visible' by every call (Function). It is a good place to put global variables as you observed.
That is in contrast with DWORD PTR SS:[EBP-30] like variables, which are located in the stack ( SS: ), and have scope within the local call (Function).

You should remeber your C 101 global versus local concept.
There are more complications and wrinkles to this story, but that is the general idea.


Oh Shit. I missed the point, completely.
Sorry.

doug
November 23rd, 2003, 16:27
Quote:
[Originally Posted by naides]Typically,
DWORD PTR DS:[580EDC] Refers to a 'global' variable, which is located in the data segment ( DS: ) and is 'visible' by every call (Function). It is a good place to put global variables as you observed.
That is in contrast with DWORD PTR SS:[EBP-30] like variables, which are located in the stack ( SS: ), and have scope within the local call (Function).

You should remeber your C 101 global versus local concept.
There are more complications and wrinkles to this story, but that is the general idea.

I was thinking that he was refering more to
push offset "72311C5AEBA713BD58..."
than what u mentionned.

run a securom exe with cmdline: "/SecuExp", u'll see where this is going

btw, this thread was 1.5 yr old, im quite sure ntsc knows where the timer is by now

[NtSC]
November 23rd, 2003, 17:20
Quote:
[Originally Posted by doug]I was thinking that he was refering more to
push offset "72311C5AEBA713BD58..."
than what u mentionned.

run a securom exe with cmdline: "/SecuExp", u'll see where this is going

btw, this thread was 1.5 yr old, im quite sure ntsc knows where the timer is by now


Haha ;-)
Did I ever say i dont know where those Timers are ?

acoder
November 24th, 2003, 14:52
Quote:
[Originally Posted by '[NtSC]']Haha ;-)
Did I ever say i dont know where those Timers are ?


The timer code I posted wasn't destinated to "answer"
NtSC, I also assumed NtSC already knew about it...

true the thread is 1.5 yr old, I just got my first securom
protected thing

however many stuff seems to stay the same...
dumped, got oep, now I need to fix special redirected apis..i'll
search a bit on the forum...

cya