PDA

View Full Version : CommView 2.3 and Asprotect memory patching


TOTEU
October 28th, 2000, 12:59
T=9000: ; HOW MANY ATTEMPTS BEFORE QUITTING
F=cv.exe: ; PROCESS TO PATCH CommView 2.3 build 67
O=callcv2.exe: ; LOADER TO CREATE
P=11DBF94/53,56,57,8B,FA,8B,F0,B2,01,B8,F8,44,1D,01,E8,41,69,FF,FF,8B/81,FA,8D,04,07,00,75,06,B8,B2,1D,71,09,C3,B8,F1,F6,C3,77,C3: ; bypass 2 MD4derived checks
P=4ECDD7/80,38,00,75/C6,00,01,EB:; no more demo(below this one, code to set various versions Professional,MultiOS etc not tested)
P=4AC58F/83,38/EB,07: ;NOT REALLY NEEDED
P=4AC5C4/8B,00/90,90: ;NOT REALLY NEEDED BUT SEE About Box after
P=48E15B/DF,E0,9E/66,33,C0: ;this is to bypass another check for expired
P=4664BA/74,08/EB,08: ;bypass NTICE and SICE check from cv.exe
P=4EB7FD/C6,00,00/C6,00,01: bypass "unlicence"

$

this is a method for memory patching Asprotect with csir.cjb.net Risc loader

first MD4 derived checksum is 09711DB2
second MD4 derived checksum is 77C3F6F1
find MD4hash by bpx MapViewOfFile immediatly after found MD4hash routine


this is quick hack:
more interesting is to set these variables:

4F6D0C dword pointer to regusername
4F6D10 dword pointer to 1 or 2 string ascii set Professional or MultiOS
4F6D14 dword pointer regusername+8AEh
4F6D18 dword UPGRADETIME
4F6D1C byte 1 licenced/0-eval
4F6D1D byte 0 good/ 1 expired
4F6D1E byte 0 idem
4F6D1F byte 0=Personal / 1 Personal or Prof or MultiOS
last value is used in combination with byte @4F6D1C

immediatelly after verifylicencecwl @0048DA28
other useful resources:
-------------
push pointer buffer to store unencrypted string
push key for decrypt
push pointer encrypted string
:0048D9C0 decryptstring procedure
----------------


if expired in registry RLS\ExtFilter2 == 1
there are other two checks randomized ( one in win.ini ADAPTER and one in LOGS):
checkexpired procedure @0048E0ED
randomize procedure @00402CE0

tsehp
October 28th, 2000, 19:40
Well done,
here's mine, uncommented (had to create it back from scratch),
but working on a win nt 2000, the asprotects addresses are not the
same :
T=10000000:
F=cv.exe:
O=cv_loader.exe:
P=d2f506/74/eb:
P=d2f564/01,04,24,c3,c3,8d,40,00/c7,04,24,6c,f5,d2,00,c3:
P=d305b5/31,04,24,e8,01,00,00,00/c7,04,24,a4,fb,d2,00,c3:
; I only remember that the two lines above are to disable the mem
;checksum of asprotect
P=d2f855/50,c3,5b,6a,10/e9,c2,34,7c,ff:
P=4ecdda/75/eb:
P=4ee64c/76/eb:
P=4eedf9/74/eb:
P=4ecd94/74/eb:
P=48e2d4/76/eb:
P=48e2e7/80,7d,ff,01,75,07/b8,20,02,12,00,90:
P=4f2d61/74/eb:
P=4eb5f1/0f,84,90,00,00,00/90,90,90,90,90,90:
P=4664ba/74/eb:
P=48e3b3/75/eb:
$

I didn't attempted to recreate the iat, did you ?

tsehp

TOTEU
October 28th, 2000, 20:23
Of course not...I'm _lazy_ after all...And, remember my post on the old board, in version 1.05 I applied the same tehnique
but the checksums were CRC32hashes..

Regards,
TOTEU

PS:
Did you notice the check for Numega Softice Loader by FindWindow in Essential Nettools..an old version...2.2 build 51.I'll check the latest to see if they changed the code..

The Owl
October 29th, 2000, 05:16
and what about iceload?

tsehp
October 29th, 2000, 18:15
And alex did some changes in asprotect 1.1, an int2e calls (in winnt)
a win32 function (can't remember the name) that voids dr0-dr3 about
120 times before the entry point. Nice work. Didn't tried iceload,
but if asprotect voids the debug registers and tests dr7 for >400, then
iceload is useless to me.
Sice seems to loose easily control about the debug registers, you have
to wait for certain calls to occur (mem copy fox example)while tracing the prog to watch softice update those registers. I'll ask numega to fix
this

The Owl
October 30th, 2000, 08:14
Quote:

And alex did some changes in asprotect 1.1, an int2e calls (in winnt)
a win32 function (can't remember the name)


when you do, please post it here ;-)

Quote:

Didn't tried iceload, but if asprotect voids the debug registers and tests dr7 for >400, then iceload is useless to me.


actually, i suggested iceload for avoiding that FindWindow trick mentioned before, of course iceload has nothing to do w/ DRx. reminds me, under win9x icedump enforces 0x400 (instead of 0x700) in DR7 (whenever no DRx type BPs are set of course). this and the tracer should be able to do it, however i did not have time to test this myself.

tsehp
October 30th, 2000, 12:43
Here it is,
lots of time, asprotect 1.1 calls an int 2e to 804668b0+a8c with param=2
you trace a little and you land here :
00462BB9 jz near ptr byte_462C84+1
00462BBF
00462BBF loc_462BBF: ; CODE XREF: .text:00462BB0j
00462BBF mov ebx, dr0
00462BC2 mov ecx, dr1
00462BC5 mov edi, dr2
00462BC8 mov [ebp+18h], ebx
00462BCB mov [ebp+1Ch], ecx
00462BCE mov [ebp+20h], edi
00462BD1 mov ebx, dr3
00462BD4 mov ecx, dr6
00462BD7 mov edi, dr7
00462BDA mov [ebp+24h], ebx
00462BDD mov [ebp+28h], ecx
00462BE0 mov ebx, 0
00462BE5 mov [ebp+2Ch], edi
00462BE8 mov dr7, ebx
00462BEB mov edi, large fs:20h
00462BF2 mov ebx, [edi+2F8h]
00462BF8 mov ecx, [edi+2FCh]
00462BFE mov dr0, ebx
00462C01 mov dr1, ecx
00462C04 mov ebx, [edi+300h]
00462C0A mov ecx, [edi+304h]
00462C10 mov dr2, ebx
00462C13 mov dr3, ecx
00462C16 mov ebx, [edi+308h]
00462C1C mov ecx, [edi+30Ch]
00462C22 mov dr6, ebx
00462C25 mov dr7, ecx
00462C28 jmp short near ptr byte_462C84+1

Don't pay attention to the fake addresses, in himem it corresponds to
0x804668b0+a8c , its the exReleaseResourceForThread API from ntoskrnl.exe on winnt.
This surely voids your debug registers and impeach a bpmb.
The quick crack, force to jump at 462bb9 (listing address).
The same routine is repeated about 8 times in ntoskrnl, you have to patch them all, then you can put some bpmb's again.
Regards,

tsehp

risc
October 30th, 2000, 14:40
he clears dr0..3 in his many exception handlers..

add dword ptr [eax+0B8h], 2 ; increase eip in context struct to point past dodgy opcode
push ecx
xor ecx, ecx
mov [eax+4], ecx ; clear dr0 in context struct
mov [eax+8], ecx ; dr1..
mov [eax+0Ch], ecx ; dr2..
mov [eax+10h], ecx ; dr3..
mov dword ptr [eax+18h], 155h ; dr7 -> 101010101h ..
pop ecx
loc_40ED89:
xor eax, eax ; we handled exception.. blah
retn ; return contol to system..

which will in turn call _vwin32_set_thread_context on win9x, or int 2eh on NT/2k :/

_vwin32_set_thread_context is a lot simpler to patch than the NT equivlent.

wouldnt it be terrible if he stored decrypt keys or such in the debug registers, instead of 00000000 ..

alias
October 30th, 2000, 18:36
Can you please post the code that calls int 2eh
(i.e., what is put into eax and edx)?

This seems to do what SetThreadContext() can't on NT/2000.

tsehp
October 30th, 2000, 21:29
Sure,
here's the code on a winnt 2k service pack 1
inside asprotect 1.1, to get there first do a bpx getmodulehandlea
do "stack" until you see that it was called from asprotect.
do 3 p rets, disable bpx
bpx regclosekey, then F5
trace a little, you land here, the disassembly shows bogus code, it
does small jumps so the code is not what you see. real addresses.
seg0000:d304f2 call near ptr 4D80h
seg000304F7 add al, 0EBh
seg000304F9 add ax, bp
seg000304FB mov [bx+si+8], cx
seg000304FE jmp short near ptr 501h
seg00030500 ; ---------------------------------------------------------------------------
seg00030500 call near ptr 4D8Ch
seg00030503 or al, 0EBh
seg00030505 add ax, bp
seg00030507 mov [bx+si+10h], cx
seg0003050A jmp short near ptr 50Eh
seg0003050C ; ---------------------------------------------------------------------------
seg0003050C int 20h ; DOS - PROGRAM TERMINATION
seg0003050C ; returns to DOS--identical to INT 21/AH=00h
seg0003050E ; ---------------------------------------------------------------------------
seg0003050E mov word ptr [bx+si+18h], 55h
seg0003050E ; ---------------------------------------------------------------------------
seg00030513 db 0 ;
seg00030514 db 0 ;
seg00030515 ; ---------------------------------------------------------------------------
seg00030515 jmp short near ptr 518h
seg00030517 ; ---------------------------------------------------------------------------
seg00030517 call near ptr 0F073h
seg0003051A add ax, bp
seg0003051C xor ax, ax
seg0003051E retn -> this one leads to
77f8e064, then one ret and finally get into the call to 77f820f3, heres
the int 2e :

seg000:77F820F3 mov ax, 1Ch
seg000:77F820F3 ; ---------------------------------------------------------------------------
seg000:77F820F6 db 0 ; <- bad translation
seg000:77F820F7 db 0 ;
seg000:77F820F8 db 8Dh ;
seg000:77F820F9 ; ---------------------------------------------------------------------------
seg000:77F820F9 push sp
seg000:77F820FA and al, 4
seg000:77F820FC int 2Eh <-there you are seg000:77F820FC ; DS:SI -> counted CR-terminated command string
seg000:77F820FE jmp near ptr 892Ah
seg000:77F820FE ; ---------------------------------------------------------------------------
Are you thinking about hooking the int 2e ? I didn't manage to guess
the return point before this call.

tsehp

alias
October 31st, 2000, 00:37
I am thinking of hooking the system service dispatch table (SSDT).
The value of eax just before int 2eh gives the service number. Once you know this,
you can hook that service using the method given in
"Undocumented Windows NT" by Dabak et al. (a short driver
that calls ntoskrnl!KeServiceDescriptorTable() to get the
address of the SSDT, and patches the SSDT entry indexed by
the service number)

alias
October 31st, 2000, 00:42
I am thinking of hooking the system service dispatch table (SSDT).
The value of eax just before int 2eh gives the service number. Once you know this,
you can hook that service using the method given in
"Undocumented Windows NT" by Dabak et al. (a short driver
that calls ntoskrnl!KeServiceDescriptorTable() to get the
address of the SSDT, and patches the SSDT entry indexed by
the service number)

alias
October 31st, 2000, 00:50
I am seeing double...