MASM32 Executable Protect Examples

Mako is insane.
Decennium
Joined
Sep 10, 2007
Messages
968
Reaction score
815
These are small examples I've made for my anti-hack, note I did change the addresses and I'm using pre-protected pages. What you may need to do is change it up to fit your executable base. I will not give support on compiling / implementing, but I can help you understand what it does.

Return Address Checking:
PHP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;Return Address Check;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;Theoretical - MASM32;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.386
include \masm32\include\masm32rt.inc
.code

start:
	call ObtainEIP

ObtainEIP:
	pop ebp
	add ebp, VirtualProtectPointer-ObtainEIP
	mov ebx, [ebp] ;EBX = VirtualProtectPointer
	mov ecx, [VirtualProtectPointer-FinalCode] 
	mov eax, [CodeAddress-VirtualProtectPointer]
	mov eax, [ebp+4]
	
	push eax
	push ecx
	push ebx
	push 40h
	push ecx
	push eax
	call dword ptr ds:[005E62F4h] ;VirtualProtect
	pop ecx
	pop eax
	
	lea edi, [eax]
	sub ebp, [VirtualProtectPointer-FinalCode]
	lea esi,[ebp]
	rep movs byte ptr es: [edi], byte ptr ds: [esi]
	retn

FinalCode:
	push eax
	mov [esp+4],eax
	pop eax
	mov eax, [esp+4]
	cmp eax,00640000h
	jg HackDetected
	cmp eax, 00401000h
	jle HackDetected
	pop eax
	retn
HackDetected:
	mov eax, 006A0000h
	lea eax, [eax]
	PUSH 1
	call eax ;Send packet to the server
	push 0
	CALL DWORD PTR DS:[005E62B4h]
	pop eax
	retn
VirtualProtectPointer dd 006B0000h
CodeAddress dd 005DEEDFh
end start

Notice: A return address check is not always useful, you can make a naked function and push a fake return address that is inside the code base, then do an unconditional jump to it.

Send Packet:
PHP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;Hack Checking Packet;;;;;;;;;;;
;;;;;;;;;;;;;;;Theoretical - MASM32;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.386
include \masm32\include\masm32rt.inc
.code

start:
	call ObtainEIP
	
ObtainEIP:
	pop ebp
	add ebp, PacketPointer-ObtainEIP
	mov eax, [ebp+4]
	mov ecx, PacketPointer-FinalCode
	mov edx, [ebp]
	
	push ecx
	push edx
	push 40h
	push 1000h
	push ecx
	push 0
	call dword ptr ds:[eax] ;VirtualAlloc
	pop edx
	pop ecx
	
	mov [edx],eax
	lea edi,[edx]
	sub ebp, [PacketPointer-FinalCode]
	lea esi,[ebp]
	rep movs byte ptr es: [edi], byte ptr ds: [esi]
	retn
;;;;;;;;;;;;;;;;;;;Code Executed;;;;;;;;;;;;;;;;;;;;;
FinalCode:
	pushad
		mov eax, [006F0000h] ;Socket
		mov eax,[eax]
		mov ebx, [006E0000h]
		mov edx, 0FF66h
		mov [ebx],edx
		mov edx, 0FF6bh
		mov [ebx+4],edx
		mov edx, 0FFCDh
		mov [ebx+8],edx
		mov edx, 90FFh
		mov [ebx+12],edx
		mov ecx, [esp+36]
		mov [ebx+14],ecx
		push 0
		push 32
		push ebx
		push eax
		call dword ptr ds:[005E65C4h]
	popad
	retn
;;;;;;;;;;;;;;;;;;;Variable Definitions;;;;;;;;;;;;;;
PacketPointer dd 006A0000h
VirtuallAllocAddress dd 005E62ECh

end start
Notice: This requires a hook on send() to save the socket identifier, so I suggest you do that. If you want to do it from C++ it would basically be this:

PHP:
int nSocket = 0;
int __cdecl sendDetour (int fd, char *pData, int nSize, int nFlags) {
   nSocket = fd;
   return sendOriginal (fd, pData, nSize, nFlags);
}
Like I said, nothing complex.

I may add more to this as I develop them or I may not.
 
nice
10char

Pointless post.



Has this been tested? It doesn't seem to be very generic, rather the way you derived some of the things seems to assume knowledge about the module you're trying to protect (other than the hardcoded constants). Personally:

mov ecx, [VirtualProtectPointer-FinalCode]

doesn't make sense. You use 'ecx' in your VP call as the size, however you're taking the value at VPP-FC, but this doesn't logically work out as the address of a size in memory, generically speaking.


Also, I see why you pop ebp (puts retaddr to start call at [esp] so retn will return properly), however, why do you do the following line which simplifies:

Code:
ObtainEIP:
pop ebp  ; - ebp -- return address, which is ObtainEIP
add ebp, VPP-ObtainEIP ; this is literally: ObtainEIP + VPP - ObtainEip = VPP
mov ebx, [ebp] ; ebx = [VPP]

Why don't you just add esp, 4, then do mov ebx, [VPP].

Also, you don't use EBP until after the VP call, but then you have no guarantee that ebp hasn't been modified unless an assumption is made.


Also, why don't you take arguments to your code -- namely the VP ptr, code address, etc, passed on the stack. Then it'd be totally generic :p.
 
Pointless post.



Has this been tested? It doesn't seem to be very generic, rather the way you derived some of the things seems to assume knowledge about the module you're trying to protect (other than the hardcoded constants). Personally:

mov ecx, [VirtualProtectPointer-FinalCode]

doesn't make sense. You use 'ecx' in your VP call as the size, however you're taking the value at VPP-FC, but this doesn't logically work out as the address of a size in memory, generically speaking.


Also, I see why you pop ebp (puts retaddr to start call at [esp] so retn will return properly), however, why do you do the following line which simplifies:

Code:
ObtainEIP:
pop ebp  ; - ebp -- return address, which is ObtainEIP
add ebp, VPP-ObtainEIP ; this is literally: ObtainEIP + VPP - ObtainEip = VPP
mov ebx, [ebp] ; ebx = [VPP]

Why don't you just add esp, 4, then do mov ebx, [VPP].

Also, you don't use EBP until after the VP call, but then you have no guarantee that ebp hasn't been modified unless an assumption is made.


Also, why don't you take arguments to your code -- namely the VP ptr, code address, etc, passed on the stack. Then it'd be totally generic :p.

The whole reason I didn't do that is the main reason of RCE I'm using. When the bytes are received I simply call the function. The way I'm doing this is to make it so that those are just stored, also the whole reason for the VPP-ObtainEIP is to get the location of the table. Notice that the table is still located inside of the main function, so I need to obtain the values from it.
mov ecx, [VirtualProtectPointer-FinalCode]
That is a really generic way of getting the size of FinalCode.
 
The whole reason I didn't do that is the main reason of RCE I'm using. When the bytes are received I simply call the function. The way I'm doing this is to make it so that those are just stored, also the whole reason for the VPP-ObtainEIP is to get the location of the table. Notice that the table is still located inside of the main function, so I need to obtain the values from it.
mov ecx, [VirtualProtectPointer-FinalCode]
That is a really generic way of getting the size of FinalCode.

I see. I was confused, I didn't notice the dd declaration on your labels, I thought they were constants which made a lot of that not make sense :p. It changes a lot when you make that realization.

I still think there are a few mistakes though, and you set eax then set eax again (redundant) -- the first is obviously wrong, it *SHOULD* evaluate to [4] which probably will result in a segfault on the target machine. ebp+4 seems right for what you're trying to do.


Return Address Checking:

PHP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;Return Address Check;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;Theoretical - MASM32;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.386
include \masm32\include\masm32rt.inc
.code

start:
    call ObtainEIP

ObtainEIP:
    ; Fixup stack
    add esp, 4

    mov ebx, VirtualProtectPointer
    mov ecx, VirtualProtectPointer-FinalCode
    mov eax, [CodeAddress]

    ; Save eax,ecx
    push eax
    push ecx

    ; Call Virtual protect
    push ebx ; oldflags
    push 40h ; newflags
    push ecx ; size
    push eax ; addr
    call dword ptr ds:[005E62F4h] ;VirtualProtect

    ; Resore ecx,eax
    pop ecx
    pop eax

    ; Set esi/edi for rep mov
    mov edi, eax
    mov esi, FinalCode
 
    ; Copy bytes
    rep movs byte ptr es: [edi], byte ptr ds: [esi]

    retn


FinalCode:
    push eax
    mov eax, [esp+4]
    cmp eax,00640000h
    jg HackDetected
    cmp eax, 00401000h
    jle HackDetected
    pop eax
    retn

HackDetected:
    push 1
    call dword ptr ds:[006A0000h] ;Send packet to the server

    push 0    
    call dword ptr ds:[005E62B4h]

    pop eax
    retn
; Variables
VirtualProtectPointer dd 006B0000h
CodeAddress dd 005DEEDFh
end start

Just a quick edit, what do you think about this? I'd step it still, and test it to ensure it works, but the idea is simple. You insert your own stub and write it at 005DEEDF after VP'ing it, and if the caller is not within the code range of the module you're protecting the 'HackDetected' code is executed. But how exactly are you planning on applying this? As in, how will you get execution flow to enter that code?
 
Last edited:
You're now relying on the address and not the table. That's the whole issue with that, this NEEDS to be static and dynamic.
 
?? It should do the same thing that your code intended above.

no no no, the whole reason I get the EIP / pop ebp, is so I can grab the location of the table. What you're doing is using the address which will be dynamic and won't work for this use. The point of the table is to have the addresses inside that base.
 
no no no, the whole reason I get the EIP / pop ebp, is so I can grab the location of the table. What you're doing is using the address which will be dynamic and won't work for this use. The point of the table is to have the addresses inside that base.

I see what you mean, but some of those statements of yours are still wrong and will cause a segfault, that's all.

And I never see an explanation of how you're going to get program flow to enter your stub :p.
 
I just noticied that in that send hok I used __cdecl instead of __stdcall. I'm too lazy to fix it, but yeah ;3
 
Back