I am working on a project where I would like for the address where my numbers are stored to change each time the program is restarted. Here is my code:


invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE
mov  hMemory,eax
invoke GlobalLock,hMemory
mov  pMemory,eax
mov    pMemory,30


All my allocations are setup fine but the actual address where the memory is located does not change when the program is restarted. I would like for this to happen. Any ideas?
Posted on 2006-01-15 19:16:08 by resistance_is_futile
There's very high chance that the memory allocation will get the same addres (given the same allocation size) upon every application restart (well it's even relatively high upon every OS restart).

1) if you allocate more than 1 chunks of mem (say 5-6), then just allocate them in different order every time you start your app. The chunks will have same addresses, but each time they're reatarted, will contain different data. (this is what Blizzard's Diablo 2 does)
2) allocate a bit more bites, then create a random number and store your data at the allocated chunk offset by the random number. Don't forget to Free the memory using the original pointer - not the offset one.
3) Highly fragment the memory then allocate required chunk. (Not recommended :P)
Posted on 2006-01-15 19:35:15 by ti_mo_n
rif,

With an old API like GlobalAlloc() it is advisable to use the FIXED flag as the rest of its capacity is effectively out of date. If what you want is a different address each start, the suggestion from ti_mo_n is a good one and all you need to do is use an API like GetTickCount() as a seed to alter the offset each time you start the app. I gather you are trying to defeat something like in memory patching and this will make it harder for them to access your program but try out another idea in conjunction with it, change the allocation order each time the app starts up for different memory blocks and it will make the address even harder to track.
Posted on 2006-01-15 22:23:22 by hutch--
Okay this is what I have and it does not seem to be working..



invoke GlobalAlloc,GMEM_FIXED,MEMSIZE
mov  pMemory,eax
invoke GlobalHandle,pMemory
mov aMemory,eax
invoke GetTickCount
add aMemory,eax
invoke GlobalLock,aMemory
mov aMemory,eax
mov aMemory,30
Posted on 2006-01-16 03:53:11 by resistance_is_futile
resistance, you don't need GlobalLock when you use the GMEM_FIXED flag to GlobalAlloc. But you might as well use HeapAlloc anyway, since that's what GlobalAlloc does internally.

As for the usefulness of this, for somebody RE'ing your app it would be trivial to find the allocation calls and fetch the pointers you're storing...  resistance IS futile :)
Posted on 2006-01-16 04:31:14 by f0dder
I realize that the returned value is the pointer. I just read a few articles that convinced me lol. I know it would be easy to RE my program.. That is kind of the point of the program. However, I cannot discuss this here, thus leading to short code postings and program reference. Another method of RE'ing my program is to simply use a debugger to re-write the programs actual instructions in memory. As said before, I would very much like to get this program working any help is much appreciated. I want to go with the random number via GetTickCount() but I do not know how to go about in changing the code to suit my needs.


Posted on 2006-01-16 04:58:36 by resistance_is_futile
Well, use HeapAlloc to allocate a block of memory + some_extra_amount. Store this (base) pointer (you'll need it when freeing the memory later). Next, call GetTickCount (or use RDTSC), mask by some value, and add that to the base pointer - store this pointer, this will be what you use for accessing the memory.

Let's say you need to allocate 1024 bytes:


MAGIC_VALUE equ 64 ; just some size

.data?
baseptr DWORD ?
usedptr DWORD ?

.code

invoke GetModuleHandle, 0
invoke HeapAlloc, eax, 0, 1024 + MAGIC_VALUE
mov , eax
mov , eax

rdtsc
and eax, MAGIC_VALUE
add , eax


You use usedptr when referring to your memory, and baseptr when you need to free the memory again. rdtsc is better than GetTickCount since it's harder to break on (requires access to a control register etc.) - and I doubt you'll find anybody today running windows on less than a pentium.
Posted on 2006-01-16 07:32:25 by f0dder
resistance_is_futile,

There is a trick that is a left over from hash tables and that is to set the numeric range of deviation you require as offset variation in your allocated buffer then feed the GetTickCount result to a modulo of the offset range. This means you have a fast and reasonably random way to alter the offset each time your app starts that is always within the range you set.

This is the basic idea as a code snippet

    xor edx, edx        ; clear EDX
    mov eax, tickcount  ; GetTickCount result
    div cnt            ; offset count range
    mov eax, edx        ; copy remainder of division to EAX


Just check the result as I grabbed this out of a hash table example I have without testing it in your context.
Posted on 2006-01-16 09:24:05 by hutch--

invoke  GetModuleHandle,0
mov ,eax
invoke HeapAlloc, eax,HEAP_ZERO_MEMORY, 1024 + MAGIC_VALUE
mov , eax
mov , eax
invoke GetTickCount
and eax, MAGIC_VALUE
add , eax


okay this returns an error


invoke  GetProcessHeap
mov ,eax
invoke HeapAlloc, eax,HEAP_ZERO_MEMORY, 1024 + MAGIC_VALUE
mov , eax
mov , eax
invoke GetTickCount
and eax, MAGIC_VALUE
add , eax


This works fine but does not change the address of the value in the allocated block..
Posted on 2006-01-16 20:08:57 by resistance_is_futile
*cough* sorry, of course you need GetProcessHeap and not GetModuleHandle. Also, it should be "and eax, MAGIC_VALUE-1", where MAGIC_VALUE must be a power of two - if you want non-powers-of-two, do a DIV and use the modulus (like the code hutch pasted).

And really, rdtsc instead of GetTickCount. Just ".586" (or perhaps .586p if masm is picky) at the top of your code instead of the usual .386.
Posted on 2006-01-16 20:52:50 by f0dder
You will not change the offset this way as it is assemble time, not run time calculated.

1024 + MAGIC_VALUE

You need to calculate the "MAGIC_VALUE" at runtime then add it to the normal start address with ADD.

The current method you are using will always be the same as its built into the executable file as a single value. (1024+offset).

Here is a quick way to do what you are after. Its written in expanded form so its clear to understand.


; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
    include \masm32\include\masm32rt.inc
; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

comment * -----------------------------------------------------
                        Build this  template with
                      "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
 
; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

    call main
    inkey
    exit

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

main proc

    LOCAL hMem  :DWORD      ; the original memory handle
    LOCAL pMem  :DWORD      ; the offset to memory to use
    LOCAL rang  :DWORD      ; integer range of additional offset
    LOCAL tcnt  :DWORD      ; variable for GetTickCount

    mov rang, 65536        ; 64k offset range

    invoke GlobalAlloc,GMEM_FIXED,1024*1024    ; allocate 1 meg
    mov hMem, eax                              ; copy return address to a pointer

    invoke GetTickCount
    mov tcnt, eax

    xor edx, edx            ; clear EDX
    mov eax, tcnt          ; GetTickCount result
    div rang                ; offset count range

    mov eax, hMem
    add eax, edx            ; add the remainder to the original memory address

    add eax, 7              ; align the data by 8 bytes
    and eax, -8

    mov pMem, eax          ; unique offset each time its run.

  ; ****************
  ; show the results
  ; ****************
    print str$(edx)," added offset to memory",13,10
    print str$(hMem)," original memory address",13,10
    print str$(pMem)," altered memory address",13,10

    invoke GlobalFree,hMem  ; free the original memory handle when finished

    ret

main endp

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

end start


PS: Something I should have mentioned, instead of an offset in the range of 0 to 65535, you will get better results again by using a prime number just over or just under the range you require as you will always get a remainder that way.
Posted on 2006-01-17 01:06:56 by hutch--

You will not change the offset this way as it is assemble time, not run time calculated.

Sure he will, since a (AND bounded/masked) rdtsc value is added later on. You could argue, though, that using a different alloc size (not just a different add value) would be a good idea, since it makes it harder to do a heap walk and find right-sized blocks.

Aligning the memory like hutch does is a good idea btw, to avoid performance penalties. Addresses won't be *just* as random, but should still be fine.

Oh, and never make a "RandomAlloc proc" since this will give attackers a single point of attack - a macro would be better.

Posted on 2006-01-17 02:44:34 by f0dder
okay well i tried a few things.. Rearranging code, etc. However, none of this code is giving me what I want. Here is the code and results:


.386
.model flat,stdcall
option casemap:none

include training.inc

.code

start:
mov rang, 65536

    invoke GlobalAlloc,GMEM_FIXED,1024*1024
    mov hMem,eax
   
    invoke GetTickCount
    mov tcnt,eax
   
    xor edx,edx
    mov eax,tcnt
    div rang
    mov eax,edx
   
    ; Here I tried something a little different and get the same result each time
    ;mov eax,hMem
    mov eax,
    ;add eax,edx
   
    add eax,7
    and eax,-8
    mov pMem,eax

   
invoke GetModuleHandle,NULL
mov    hInstance,eax
invoke GetCommandLine
invoke InitCommonControls
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax


Now when the processes memory is searched for the value, I retrieve the same address each time.. This address would be 00403085. I want this address to change. I do not know if maybe there was a misunderstanding or what. All the numbers are generated fine and very random. But it seems that this is where it is going wrong:


    ; Here I tried something a little different and get the same result each time
    ;mov eax,hMem
    mov eax,
    ;add eax,edx


The new address is not calculated and does not change. Really weird considering everything else works perfect. Any ideas guys?
Posted on 2006-01-17 02:54:27 by resistance_is_futile
resistance_is_futile,

I actually code that small example so you had a working method of changing a buffer offset each time the app started. Now while its not the only way to perform such a task, it does work correctly and I suggest that you should actually bother to put it into a file and build it to see that it does deliver different results each time it starts.

Once you actually understand what is going on you can code whatever you like but you need to know enough about it first to do that.


    1024 + MAGIC_VALUE


You may have read the wrong part of the posting, both values are added at assembly time and are inserted into the code as an immediate.
Posted on 2006-01-17 03:31:03 by hutch--
Edit: Just got a hold of the latest macro file release...

However, inkey is not working for some reason (wait_key issue?).

Any I did try to compile your program before, but was a little behind on a macro file release. it compiled fine. So how exactly do i implement this method into my win32 program? I dont want to just show the results. I need to use the address to store a changing number.
Posted on 2006-01-17 03:45:48 by resistance_is_futile
resistance, here's a fully working test app that shows how to do it with a MACRO for ease of use.

RDTSC is used insted of GetTickCount to make breaking on the random-alloc a bit harder - this requires a pentium, but who runs windows on a 486 these days? :)

EDIT: posted the code inline as well, it's small enough for that.


.586
.model flat,stdcall
option casemap:none
option proc:private

incAPI MACRO files:VARARG
FOR file, <files>
include file&.inc
includelib file&.lib
ENDM
ENDM

CTEXT MACRO y:VARARG
LOCAL sym

CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends

EXITM <OFFSET sym>
ENDM

include <windows.inc>
incAPI <kernel32,user32>

ASSUME FS:NOTHING

MAGIC_VALUE equ 13373 ; the max displacement - doesn't have to be a power of 2

RANDOMALLOC MACRO size:REQ, baseptr:REQ, usedptr:REQ
invoke GetProcessHeap
invoke HeapAlloc, eax, 0, size + MAGIC_VALUE

mov baseptr, eax
mov usedptr, eax

rdtsc ; get Time Stamp Counter in EDX:EAX - requires pentium
mov ecx, MAGIC_VALUE
xor edx, edx
div ecx
add usedptr, edx ; add the modulus/displacement
ENDM

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; DATA? section
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data?
free_this_later DWORD ?
use_this_pointer DWORD ?
buf BYTE 256 DUP (?)

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; CODE section
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.code

ENTRY32:
RANDOMALLOC 1024, free_this_later, use_this_pointer
; now you have a 1024-byte buffer accessible through "use_this_pointer". once you're
; done and want to free the memory, you free the base pointer - "free_this_later".
invoke wsprintf, addr buf, CTEXT("Pointer: %d"), use_this_pointer
invoke MessageBox, 0, addr buf, CTEXT("Check this out"), MB_OK

; just for fun, fill the buffer
mov edi, use_this_pointer
mov ecx, 1024/4
rep stosd

; free the memory
invoke GetProcessHeap
invoke HeapFree, eax, 0, free_this_later

invoke ExitProcess, 0

END ENTRY32

Attachments:
Posted on 2006-01-17 04:59:52 by f0dder
As I now know what you are trying to do, here is an example that shows you one way of doing it. This one uses the nrandom procedure from the masm32 library. I have commented out the "inkey" and it should build OK with your installation.

Now what you need to do to get the swing of this is to pull your head OUT of a debugger at the moment and do a bit of simple software engineering first.

It allocates 16384 DWORD slots in memory, fills them full of random junk in approximately addressing DWORD range then it generates a random location within that 16k range for your own variable to be placed. The reason for doing this is they will not find you variable with a simple search of the memory as it is already filled with junk. You can play with the fill range so it better matches the range in which your variable occurs.


; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
    include \masm32\include\masm32rt.inc
; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

comment * -----------------------------------------------------
                        Build this  template with
                      "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *
    .code
start:
 
; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

    call main
    ;;;; inkey
    exit

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

main proc

    LOCAL hMem  :DWORD      ; the original memory handle
    LOCAL pMem  :DWORD      ; the offset to memory to use

  ; *********************
  ; allocate 16384 DWORDS
  ; *********************
    invoke GlobalAlloc,GMEM_FIXED,16384*4
    mov hMem, eax

    invoke GetTickCount
    invoke nseed, eax          ; seed the random generator

    push esi
    push edi

    mov esi, 16384              ; loop this many times
    mov edi, hMem              ; put buffer address in edi
  ; *******************************
  ; fill buffer full of random junk
  ; *******************************
  lpst:
    invoke nrandom,1024*1024*4  ; 4 meg range of random numbers
    add eax, 1024*1024*4        ; add 4 meg
    mov , eax              ; write result to buffer
    add edi, 4                  ; set next address in buffer
    sub esi, 1
    jnz lpst

    pop edi
    pop esi

  ; ****************************************
  ; create the location for your own address
  ; ****************************************
    invoke GetTickCount
    invoke nseed, eax          ; reseed the random generator
    invoke nrandom,16384        ; range is 16384
    lea eax,             ; multiply by 4 for aligned location

  ; *********************************************
  ; add the offset to the original memory address
  ; *********************************************
    mov edx, hMem
    add edx, eax
    mov pMem, edx              ; <<<< This is the address to write your variable to

  ; *******************
  ; display the results
  ; *******************
    print str$(hMem)," original memory address",13,10
    print str$(pMem)," altered memory address",13,10

    invoke GlobalFree,hMem  ; free the original memory handle when finished

    ret

main endp

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

end start
Posted on 2006-01-17 07:29:37 by hutch--
The additional 16k-index buffer indirection buys you nothing, since you can still read the hmem and pmem values and use those directly...

But whatever. resistance, choose what you want. I know which one I'd choose personally :)
Posted on 2006-01-17 07:46:07 by f0dder
Usually what happens is if someone uses a particular idea, they don't lay it out in simplified form complete with commentary to show how its done. Filling the buffer just prevents scanning the buffer for the first non zero value and as it changes every time the app starts, there is no established pattern of memory usage.

What you tend to do when you need to do something like this is use a very UNsimplified method. You certainly could lay the app out so that the two memory pointers were easy to find but its no big deal to make them much harder to find and track. The range of tricks are many but finally this type of random location of a variable is what he was after so I have tried to make the example simple enough to understand.

We all know the theory that you can break anything if you take long enough and the best you can do is stretch the time spent in disassemblers, debuggers and the like to try and get the job done. If it takes long enough, you have succeeded.

Regards,

hutch at movsd dot com
Posted on 2006-01-17 09:42:48 by hutch--

resistance, here's a fully working test app that shows how to do it with a MACRO for ease of use.

RDTSC is used insted of GetTickCount to make breaking on the random-alloc a bit harder - this requires a pentium, but who runs windows on a 486 these days? :)

EDIT: posted the code inline as well, it's small enough for that.


.586
.model flat,stdcall
option casemap:none
option proc:private

incAPI MACRO files:VARARG
FOR file, <files>
include file&.inc
includelib file&.lib
ENDM
ENDM

CTEXT MACRO y:VARARG
LOCAL sym

CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends

EXITM <OFFSET sym>
ENDM

include <windows.inc>
incAPI <kernel32,user32>

ASSUME FS:NOTHING

MAGIC_VALUE equ 13373 ; the max displacement - doesn't have to be a power of 2

RANDOMALLOC MACRO size:REQ, baseptr:REQ, usedptr:REQ
invoke GetProcessHeap
invoke HeapAlloc, eax, 0, size + MAGIC_VALUE

mov baseptr, eax
mov usedptr, eax

rdtsc ; get Time Stamp Counter in EDX:EAX - requires pentium
mov ecx, MAGIC_VALUE
xor edx, edx
div ecx
add usedptr, edx ; add the modulus/displacement
ENDM

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; DATA? section
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data?
free_this_later DWORD ?
use_this_pointer DWORD ?
buf BYTE 256 DUP (?)

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; CODE section
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.code

ENTRY32:
RANDOMALLOC 1024, free_this_later, use_this_pointer
; now you have a 1024-byte buffer accessible through "use_this_pointer". once you're
; done and want to free the memory, you free the base pointer - "free_this_later".
invoke wsprintf, addr buf, CTEXT("Pointer: %d"), use_this_pointer
invoke MessageBox, 0, addr buf, CTEXT("Check this out"), MB_OK

; just for fun, fill the buffer
mov edi, use_this_pointer
mov ecx, 1024/4
rep stosd

; free the memory
invoke GetProcessHeap
invoke HeapFree, eax, 0, free_this_later

invoke ExitProcess, 0

END ENTRY32




okay now what about setting the value at the address to 30 (which is like 1E in hex) and increasing it by one
after a certain action like lets say a button is pushed? wouldn't it be something like this:


mov , 1Eh

then..

.if wParam == 1001
  inc
.endif


right? Just checking before I go jumping into it
Posted on 2006-01-18 01:53:22 by resistance_is_futile