flat assembler
Message board for the users of flat assembler.

Index > Windows > writeprocessmemory problem

Author
Thread Post new topic Reply to topic
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 16 May 2013, 17:47
i have looked everywhere, tried everything and nothing. im writing a program that runs another program and patches it in memory before it starts up, but the program doesnt get patched. WriteProcessMemory always returns error 0x5 access denied or 0x6 invalid handle
Code:
        mov     dword[StartUpInfo.cb],sizeof.STARTUPINFO
        invoke  CreateProcess,0,commandline,0,0,0,CREATE_SUSPENDED,0,0,StartUpInfo,ProcessInfo
        test    eax,eax
        jz      .end
        invoke  OpenProcess,PROCESS_ALL_ACCESS,0,dword[ProcessInfo.dwProcessId]
        mov     dword[hProcess],eax    


virtualprotectex and writeprocessmemory goes here

Code:
        invoke  ResumeThread,dword[ProcessInfo.hThread]
        invoke  WaitForSingleObject,dword[hProcess],-1
        invoke  CloseHandle,dword[ProcessInfo.hProcess]
        invoke  CloseHandle,dword[ProcessInfo.hThread]
        invoke  CloseHandle,dword[hProcess]    


what am i doing wrong?
Post 16 May 2013, 17:47
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 767
tthsqe 16 May 2013, 19:26
The forum member here revolution would ask you to post all of the code or at least enough so that we reproduce your problem... Wink
Post 16 May 2013, 19:26
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 16 May 2013, 19:50
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 20:46; edited 3 times in total
Post 16 May 2013, 19:50
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 16 May 2013, 21:17
i would post the whole source code but its part from an anti-cheat.. Sad

Code:
proc MemoryPatchEx handle,destination,source,num

locals
        flOldProtect dd ?
endl
        push    ebx ecx edx edi esi
        mov     ebx,dword[handle]
        mov     edi,dword[destination]
        mov     esi,dword[num]
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtectEx,ebx,edi,esi,PAGE_EXECUTE_READWRITE,eax
        invoke  WriteProcessMemory,ebx,edi,dword[source],esi,0
        push    eax
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtectEx,ebx,edi,esi,dword[eax],eax
        pop     eax
        pop     esi edi edx ecx ebx
        ret
endp    


thats the function i use to patch. handle = hProcess

Quote:
You don't need to call "VirtualProtectEx" before calling "WriteProcessMemory"


:O really? i saw a lot of example doing it my way, like these:

http://forum.sysinternals.com/help-with-virtualprotectex-and-writeprocessmemmory_topic20012.html
http://stackoverflow.com/questions/1112339/writeprocessmemory-readprocessmemory-fail

i been hours and hours trying to find out the problem...but no luck

ps: using OpenProcess with PROCESS_ALL_ACCESS throws Invalid handle, and with PROCESS_SUSPEND_RESUME+PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WRITE throws Access denied (before the other program is started)
Post 16 May 2013, 21:17
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 16 May 2013, 21:50
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 20:46; edited 1 time in total
Post 16 May 2013, 21:50
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20309
Location: In your JS exploiting you and your system
revolution 17 May 2013, 01:25
tthsqe wrote:
The forum member here revolution would ask you to post all of the code or at least enough so that we reproduce your problem... Wink
Yes, I would do that. I would also encourage the OP to break this problem down into its simplest form and work from there. This way you don't have to reveal to us your entire code set (if you don't want to) and it removes possible problems caused by other unrelated code.

Make a very simple "victim" process and a very simple "patching" process that does only what you are trying to achieve with WriteProcessMemory and nothing else. This eliminates distractions and allows us to help you more directly rather than guessing about what you have done and what you may have done wrong.

And often what can happen is that the very process of breaking down the problem to its simplest form can help one solve the problem without the need to post to a forum and wait for replies etc. It is all about efficiency and focus.
Post 17 May 2013, 01:25
View user's profile Send private message Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 17 May 2013, 08:46
You don't need that API. As long as you called VirtualProtectEx you can access the remote process' memory by using string function like so.

Code:
patch_code dd $100 dup (0xC3)

...
cld
lea   esi, [patch_code]
mov edi, [remote_pointer]
mov ecx, $100
rep  stosd  ; move by 4 bytes since $100 is multiple of 4
    
Post 17 May 2013, 08:46
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 17 May 2013, 11:43
i was going to do that revolution, but this one doesnt throw error 5/6 lol

http://s000.tinyupload.com/index.php?file_id=73923244439383198786

i been thinking tonight and it could be due to two reason

- need SeDebugPrivilege
- dword[source] is not a pointer

typedef, but wouldnt that patch my own program instead of the other one that i want to patch?

i use this function to patch my own program

Code:
proc MemoryPatch destination,source,num

locals
        flOldProtect dd ?
endl
        push    ecx edx edi esi
        mov     edi,dword[destination]
        mov     esi,dword[source]
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,edi,dword[num],PAGE_EXECUTE_READWRITE,eax
        mov     ecx,dword[num]
        cld
        rep     movsb
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,dword[destination],dword[num],dword[eax],eax
        mov     eax,1
        pop     esi edi edx ecx
        ret
endp    
Post 17 May 2013, 11:43
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 19 May 2013, 15:05
randomdude wrote:
i was going to do that revolution, but this one doesnt throw error 5/6 lol

http://s000.tinyupload.com/index.php?file_id=73923244439383198786

i been thinking tonight and it could be due to two reason

- need SeDebugPrivilege
- dword[source] is not a pointer

typedef, but wouldnt that patch my own program instead of the other one that i want to patch?

i use this function to patch my own program

Code:
proc MemoryPatch destination,source,num

locals
        flOldProtect dd ?
endl
        push    ecx edx edi esi
        mov     edi,dword[destination]
        mov     esi,dword[source]
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,edi,dword[num],PAGE_EXECUTE_READWRITE,eax
        mov     ecx,dword[num]
        cld
        rep     movsb
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,dword[destination],dword[num],dword[eax],eax
        mov     eax,1
        pop     esi edi edx ecx
        ret
endp    


VirtualProtect = Current process
VirtualProtectEx = Remote Process

So you do
Code:
HANDLE hProcess = OpenProcess(...) ;
 if patching to a known address call VirtualProtectEx (hProcess,pMem,....) get write access, save old access)
  
 WriteProcessMemory or direct access with assembly.

VirtualProtectEx(hProcess,pMem, ... restore old access)
    

Also sometimes you have to consider session isolation (>=VISTA)
Post 19 May 2013, 15:05
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 19 May 2013, 20:39
might be that, typedef

i fixed the invalid handle problem... i was passing a pointer to hProcess instead of the value inside it

but now writeprocessmemory simply does nothing. i get error message 'There are no more files', 'Tried to access to an invalid address' and 'The parameter is incorrect'

i guess i will need to spend more time fixing these bugs than the time i spent making the program lol

thanks anyways guys for the help Smile
Post 19 May 2013, 20:39
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 20 May 2013, 04:01
What exactly are you trying to accomplish?
Just explain it and I'll show you the code.
Post 20 May 2013, 04:01
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 20 May 2013, 19:11
its simple, i wanna load another .exe and patch it in memory with createprocess + writeprocessmemory + resumethread, and additionally loop a thread to check for hacks and such

but i cant even do the simple memory patching Sad
Post 20 May 2013, 19:11
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 20 May 2013, 22:54
randomdude,

Well, this code does something similar:
Code:
        include "Win32AX.Inc"

        .code
start:  invoke  CreateProcess, _hello, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, _si, _pi
        invoke  WriteProcessMemory, [_pi.hProcess], 0x40100E, _patch, _patch.size, esp
        invoke  ResumeThread, [_pi.hThread]
        invoke  ExitProcess, 0

        .data
_hello TCHAR "Hello.Exe", 0
_patch db "Lo?"
_patch.size = $ - _patch
_si STARTUPINFO sizeof.STARTUPINFO
_pi PROCESS_INFORMATION

        .end    start    
I've used "Hello.Exe" from fasm's examples as target. Patching process doesn't have SeDebugPrivilege.

You're right (and typedef's wrong) about patching your own program with rep movsb.
Post 20 May 2013, 22:54
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 21 May 2013, 04:33
baldr wrote:
randomdude,

Well, this code does something similar:
Code:
        include "Win32AX.Inc"

        .code
start:  invoke  CreateProcess, _hello, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, _si, _pi
        invoke  WriteProcessMemory, [_pi.hProcess], 0x40100E, _patch, _patch.size, esp
        invoke  ResumeThread, [_pi.hThread]
        invoke  ExitProcess, 0

        .data
_hello TCHAR "Hello.Exe", 0
_patch db "Lo?"
_patch.size = $ - _patch
_si STARTUPINFO sizeof.STARTUPINFO
_pi PROCESS_INFORMATION

        .end    start    
I've used "Hello.Exe" from fasm's examples as target. Patching process doesn't have SeDebugPrivilege.

You're right (and typedef's wrong) about patching your own program with rep movsb.


Ahh Yes. I wasn't thinking there for a second. You're right. reb movsb doesn't work. That's why WriteProcessMemory requires a handle to the traget process. And if the target process is the current one then you can use rep movsb.

Sorry about this confusion I wasn't thinking there.

And btw this one will trigger access violation if the memory you are writing to is write-protected.
Post 21 May 2013, 04:33
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 22 May 2013, 14:58
Code:
        ...
        stdcall LoadExe,exefilename,exearg1
        ...
        stdcall ApplyPatches,dword[hProcess],pdror_start,num_patches,pdror_size
        ...
        stdcall RunExe,dword[ProcessInfo.hProcess],dword[ProcessInfo.hThread]
        ...    

Code:
proc LoadExe exename,exearg

        stdcall CheckExe,dword[exename]
        test    eax,eax
        jz      .end
        invoke  lstrcat,commandline,dword[exename]
        mov     eax,dword[exearg]
        cmp     byte[eax],0
        jz      .noarg
        invoke  lstrcat,commandline,space
        invoke  lstrcat,commandline,dword[exearg]
        .noarg:
        mov     dword[StartUpInfo.cb],sizeof.STARTUPINFO
        invoke  CreateProcess,0,commandline,0,0,0,CREATE_SUSPENDED,0,0,StartUpInfo,ProcessInfo
        test    eax,eax
        jz      .end
        invoke  OpenProcess,PROCESS_ALL_ACCESS,0,dword[ProcessInfo.dwProcessId] ;PROCESS_SUSPEND_RESUME+PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WRITE
        mov     dword[hProcess],eax
        .end:
        ret
endp    

i guess OpenProcess is not needed?
Code:
proc ApplyPatches process,addr,num,size

locals
        flOldProtect dd ?
endl

        push    ebx edi esi
        mov     ebx,dword[process]
        mov     edi,dword[addr]
        mov     esi,dword[size]
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,edi,esi,PAGE_READWRITE,eax
        stdcall ROR_decrypt,edi,esi
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtect,edi,esi,dword[eax],eax
        stdcall PatchExeEx,ebx,edi,dword[num]
        stdcall ApplyOptions,ebx
        pop     esi edi ebx
        ret
endp    

and in ApplyOptions,process something like
Code:
        stdcall PatchExeEx,dword[process],somepatch,1    


it doesnt seem to patch the exe at all (doesnt even return anything with GetLastError), and that exe also loads a dll where i also have to patch addresses but it uses relocation so i always get invalid address error. how could i get the base address where it gets realocated?

edit:

Code:
proc PatchExeEx handle,addr_patches,num_patches

        push    ebx ecx edi esi
        mov     ebx,dword[addr_patches]
        mov     ecx,dword[num_patches]
        test    ecx,ecx
        jz      .end
        .rep:
        mov     edi,ebx
        add     edi,4
        mov     edi,dword[edi]
        mov     esi,ebx
        add     esi,8
        stdcall MemoryPatchEx,dword[handle],dword[ebx],esi,edi
        xchg    ebx,esi
        add     ebx,edi
        dec     ecx
        jnz     .rep
        .end:
        pop     esi edi ecx ebx
        ret
endp    

Code:
proc MemoryPatchEx handle,destination,source,num

locals
        flOldProtect dd ?
endl
        push    ebx ecx edx edi esi
        mov     ebx,dword[handle]
        mov     edi,dword[destination]
        mov     esi,dword[num]
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtectEx,ebx,edi,esi,PAGE_EXECUTE_READWRITE,eax
        invoke  WriteProcessMemory,ebx,edi,dword[source],esi,0
        push    eax
        lea     eax,dword[flOldProtect]
        invoke  VirtualProtectEx,ebx,edi,esi,dword[eax],eax
        pop     eax
        pop     esi edi edx ecx ebx
        ret
endp
    
Post 22 May 2013, 14:58
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 22 May 2013, 21:56
typedef wrote:
And btw this one will trigger access violation if the memory you are writing to is write-protected.
PAGE_NOACCESS or PAGE_READONLY, to be exact. That section is already read/execute, you may insert VirtualProtectEx() call to make it execute-only — this won't change anything. Under the hood, call to NtWriteVirtualMemory() is sandwiched between two NtProtectVirtualMemory() calls, to set PAGE_EXECUTE_READWRITE protection and then restore it. Nevertheless, that won't raise exception, only set STATUS_ACCESS_VIOLATION => ERROR_NOACCESS.

----8<----
randomdude wrote:
it doesnt seem to patch the exe at all (doesnt even return anything with GetLastError), and that exe also loads a dll where i also have to patch addresses but it uses relocation so i always get invalid address error. how could i get the base address where it gets realocated?
Start small. Patch entry with int3, for example.

As for DLLs, loader hasn't snapped imports for created-suspended process yet. You may walk PEB_LDR_DATA lists, or use breakpoint at entry point to grab IAT entry for import from that DLL.
Post 22 May 2013, 21:56
View user's profile Send private message Reply with quote
randomdude



Joined: 01 Jun 2012
Posts: 83
randomdude 23 May 2013, 10:04
Quote:
As for DLLs, loader hasn't snapped imports for created-suspended process yet. You may walk PEB_LDR_DATA lists, or use breakpoint at entry point to grab IAT entry for import from that DLL.


this is chinese for me lol

btw i have a little question..i use loadlibrary+getprocadress to load all imports because some antiviruses detects my program as virus. do i need to call FreeLibrary for all imported functions when my program is going to exit?


Last edited by randomdude on 23 May 2013, 10:53; edited 1 time in total
Post 23 May 2013, 10:04
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 23 May 2013, 10:31
randomdude wrote:
this is chinese for me lol
english is enough for me too, Laughing
it's simple. first understanding what the loader does under the hood, also googling for Matt Pietrek
and here PEB links http://sites.google.com/site/x64lab/home/assembly-x64-links
http://sites.google.com/site/x64lab/home/notes-on-x64-windows-gui-programming/exploring-peb-process-environment-block

then loadlibrary+getprocadress http://sites.google.com/site/x64lab/home/notes-on-x64-windows-gui-programming/customizing-the-getprocaddress
i cannot find ATM 32bit lingo's version for the above.

AFAIK, there's no safe way to stop AV from deleting/marking stuff from time to time, unless you disable scanning in that folder

EDIT: found this http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=5996.0
i will restore the attachment on x64lab as i find it again in database. eh eh eh i am the worst lingo's fan Very Happy

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 23 May 2013, 10:31
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 May 2013, 20:02
randomdude wrote:
i have a little question..i use loadlibrary+getprocadress to load all imports because some antiviruses detects my program as virus. do i need to call FreeLibrary for all imported functions when my program is going to exit?
Upon program exit Windows will close all handles program has acquired (thus freeing DLLs that become unused).
Post 24 May 2013, 20:02
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.