Exetools  

Go Back   Exetools > General > Source Code

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 10-17-2015, 01:50
Insid3Code's Avatar
Insid3Code Insid3Code is offline
Family
 
Join Date: May 2013
Location: Algeria
Posts: 80
Rept. Given: 44
Rept. Rcvd 60 Times in 30 Posts
Thanks Given: 23
Thanks Rcvd at 99 Times in 53 Posts
Insid3Code Reputation: 60
[C/C++] Memory patcher to deal with (ASLR)

Memory patcher (loader) to deal with Address Space Layout Randomization (ASLR)

PHP Code:
#include <windows.h>
#include <stdio.h>

#ifdef _WIN64
#define CAPTION "atomos - memory patcher for chimera #01 (64-bit)"
#define EXENAME "target64.exe"
#else
#define CAPTION "atomos - memory patcher for chimera #01 (32-bit)"
#define EXENAME "target32.exe"
#endif

int iWinMain() {
    
PROCESS_INFORMATION lpProcessInfo = {0};
    
CONTEXT lpContext = {0};
    
STARTUPINFO lpStartupInfo = {0};

    
printf("%s\nFilename: %s\n\n"CAPTIONEXENAME);

    if(
CreateProcessA(EXENAME,
                      
NULL,
                      
NULL,
                      
NULL,
                      
0,
                      
CREATE_SUSPENDED,
                      
NULL,
                      
NULL,
                      &
lpStartupInfo,
                      &
lpProcessInfo))    {

        
lpContext.ContextFlags CONTEXT_FULL;
        
GetThreadContext(lpProcessInfo.hThread, &lpContext);

#ifdef _WIN64
        
ULONG_PTRpeb = (ULONG_PTR*)lpContext.Rdx;
#else
        
ULONG_PTRpeb = (ULONG_PTR*)lpContext.Ebx;
#endif
        
ULONG_PTR ImageBaseAddress NULL;

        
ReadProcessMemory(lpProcessInfo.hProcess,
                          &
peb[2],
                          (
LPVOID)&ImageBaseAddress,
                          
sizeof(ULONG_PTR),
                          
NULL);
                  
        
printf("[-] ImageBase Address     = 0x%p\n"ImageBaseAddress);

#ifdef _WIN64
        
printf("[-] EntryPoint Address    = 0x%p\n"lpContext.Rcx);
        
printf("[-] Process (PEB Address) = 0x%p\n"lpContext.Rdx);

#else
        
printf("[-] EntryPoint Address    = 0x%p\n"lpContext.Eax);
        
printf("[-] Process (PEB Address) = 0x%p\n"lpContext.Ebx);
#endif



#ifdef _WIN64
        
ULONG_PTR uTargetAddress lpContext.Rcx 0x7E;
        const 
char newByte 0x75;
#else
        
ULONG_PTR uTargetAddress lpContext.Eax 0x64;
        const 
char newByte 0x74;
#endif
        
WriteProcessMemory(lpProcessInfo.hProcess,
                           (
LPVOID)uTargetAddress,
                           &
newByte,
                           
1,
                           
NULL);

        
ResumeThread(lpProcessInfo.hThread);
        
WaitForSingleObject(lpProcessInfo.hThreadINFINITE);
    }

    return 
0;

Attached file contains (source and binary (32bit/64bit) for testing purposes)
Attached Files
File Type: rar loader.rar (6.9 KB, 28 views)
__________________
Computer Forensics
Reply With Quote
The Following 6 Users Say Thank You to Insid3Code For This Useful Post:
b30wulf (10-17-2015), CryptXor (10-17-2015), giv (10-21-2015), niculaita (10-20-2015), Sn!per X (11-27-2015), Storm Shadow (10-17-2015)
  #2  
Old 10-19-2015, 17:43
evlncrn8 evlncrn8 is offline
VIP
 
Join Date: Sep 2005
Posts: 176
Rept. Given: 36
Rept. Rcvd 54 Times in 24 Posts
Thanks Given: 47
Thanks Rcvd at 116 Times in 70 Posts
evlncrn8 Reputation: 54
better way is to use the NtQueryInformationProcess - process_basic_information method to obtain the peb address for the process, its much more reliable than using register values which might change with a service pack / os update etc..
Reply With Quote
The Following User Says Thank You to evlncrn8 For This Useful Post:
giv (10-21-2015)
  #3  
Old 10-19-2015, 19:45
Insid3Code's Avatar
Insid3Code Insid3Code is offline
Family
 
Join Date: May 2013
Location: Algeria
Posts: 80
Rept. Given: 44
Rept. Rcvd 60 Times in 30 Posts
Thanks Given: 23
Thanks Rcvd at 99 Times in 53 Posts
Insid3Code Reputation: 60
Yes, it's more safe to use Win/Native Api to get Base Address than using hard coded offsets (can be altered or modified between os version) especially if you plane to use it in production tools, MS recommendations.
__________________
Computer Forensics
Reply With Quote
  #4  
Old 10-19-2015, 23:55
bilbo bilbo is offline
Friend
 
Join Date: Jul 2004
Posts: 103
Rept. Given: 36
Rept. Rcvd 15 Times in 12 Posts
Thanks Given: 15
Thanks Rcvd at 17 Times in 11 Posts
bilbo Reputation: 15
Hi Insid3Code,

IMHO, your source code is very useful to find the image base address and the image entrypoint, but I really do not understand the use of patching one byte inside NTDLL.DLL, at EntryPoint+64/7E!

In my Window7-64, for a 32bit application, EntryPoint is at start of RtlUserThreadStart() (inside SysWOW64\ntdll.dll), and EntryPoint+0x64/0x7E are inside the exports table!

Best regards, bilbo
Reply With Quote
The Following User Says Thank You to bilbo For This Useful Post:
niculaita (10-20-2015)
  #5  
Old 10-20-2015, 00:57
Insid3Code's Avatar
Insid3Code Insid3Code is offline
Family
 
Join Date: May 2013
Location: Algeria
Posts: 80
Rept. Given: 44
Rept. Rcvd 60 Times in 30 Posts
Thanks Given: 23
Thanks Rcvd at 99 Times in 53 Posts
Insid3Code Reputation: 60
Hi bilbo,
To add support for WOW64 (32bit application on 64bit system) you need to use (Wow64GetThreadContext and WOW64_CONTEXT structure) and some system check to retrieve running environment info (32bit or 64bit).
__________________
Computer Forensics
Reply With Quote
The Following User Says Thank You to Insid3Code For This Useful Post:
giv (10-21-2015)
  #6  
Old 10-21-2015, 00:12
bilbo bilbo is offline
Friend
 
Join Date: Jul 2004
Posts: 103
Rept. Given: 36
Rept. Rcvd 15 Times in 12 Posts
Thanks Given: 15
Thanks Rcvd at 17 Times in 11 Posts
bilbo Reputation: 15
Thanks for your answer, Insid3Code,
Quote:
To add support for WOW64 (32bit application on 64bit system) you need to use (Wow64GetThreadContext
Well, that's not true if I compile your code in 32bit mode and I take as target a 32bit app; from MSDN:
Quote:
A 32-bit application can call this function on a WOW64 thread; the result is the same as calling the GetThreadContext function
Anyway, the one-byte patch (either in 32 or in 64bit mode) is yet a mistery for me...
Best regards
bilbo
Reply With Quote
  #7  
Old 10-21-2015, 01:42
Insid3Code's Avatar
Insid3Code Insid3Code is offline
Family
 
Join Date: May 2013
Location: Algeria
Posts: 80
Rept. Given: 44
Rept. Rcvd 60 Times in 30 Posts
Thanks Given: 23
Thanks Rcvd at 99 Times in 53 Posts
Insid3Code Reputation: 60
Quote:
Well, that's not true if I compile your code in 32bit mode and I take as target a 32bit app; from MSDN:
Yes, on 64bit system 32bit patcher to patch 32bit target: Wow64 support not needed. On 64bit system 64bit patcher to patch 32bit target: Wow64 support is needed.

Quote:
Anyway, the one-byte patch (either in 32 or in 64bit mode) is yet a mistery for me...
This code snippet is a demo for (chimera #01) challenge at AT4RE Forum, patching one byte to get (SUCCESS ICON ID instead of ERROR ICON ID of MessageBox)
__________________
Computer Forensics
Reply With Quote
  #8  
Old 10-21-2015, 02:20
Insid3Code's Avatar
Insid3Code Insid3Code is offline
Family
 
Join Date: May 2013
Location: Algeria
Posts: 80
Rept. Given: 44
Rept. Rcvd 60 Times in 30 Posts
Thanks Given: 23
Thanks Rcvd at 99 Times in 53 Posts
Insid3Code Reputation: 60
Code snippet updated to support Wow64 for 64bit patcher to patch 32bit target...

PHP Code:
#include <windows.h>
#include <stdio.h>

#ifdef _WIN64
#define CAPTION "atomos - memory patcher for chimera #01 (64-bit)"
#define EXENAME "target64.exe" // change it to target "target32.exe" for Wow64 test.
#else
#define CAPTION "atomos - memory patcher for chimera #01 (32-bit)"
#define EXENAME "target32.exe"
#endif

int iWinMain() {
    
PROCESS_INFORMATION lpProcessInfo = {0};
    
STARTUPINFO lpStartupInfo = {0};

    
printf("%s\nFilename: %s\n\n"CAPTIONEXENAME);

    if(
CreateProcessA(EXENAME,
                      
NULL,
                      
NULL,
                      
NULL,
                      
0,
                      
CREATE_SUSPENDED,
                      
NULL,
                      
NULL,
                      &
lpStartupInfo,
                      &
lpProcessInfo))    {

#ifdef _WIN64  // 64bit Application
        
DWORD64peb64bit;
        
DWORD32wowPeb;

        
CONTEXT lpContext64bit = {0};
        
WOW64_CONTEXT lpWoWContext = {0};

        
DWORD64 uTargetAddress64bit;
        
char newByte64bit;

        
DWORD64 uTargetAddressWow64;
        
char newByteWow64;

        
BOOL  Wow64Process FALSE;

        
IsWow64Process(lpProcessInfo.hProcess, &Wow64Process);

        if (
Wow64Process) { // Wow64 Process
            
lpWoWContext.ContextFlags CONTEXT_FULL;
            
Wow64GetThreadContext(lpProcessInfo.hThread, &lpWoWContext);
            
wowPeb = (DWORD32*)lpWoWContext.Ebx;

            
DWORD32 ImageBaseAddress NULL;
            
ReadProcessMemory(lpProcessInfo.hProcess,
                              &
wowPeb[2],
                              (
LPVOID)&ImageBaseAddress,
                              
sizeof(DWORD32),
                              
NULL);

            
printf("[-] Wow64 ImageBase Address     = 0x%08X\n"ImageBaseAddress);
            
printf("[-] Wow64 EntryPoint Address    = 0x%08X\n"lpWoWContext.Eax);
            
printf("[-] Wow64 Process (PEB Address) = 0x%08X\n"lpWoWContext.Ebx);

            
uTargetAddressWow64 lpWoWContext.Eax 0x64;
            
newByteWow64 0x74;

            
WriteProcessMemory(lpProcessInfo.hProcess,
                               (
LPVOID)uTargetAddressWow64,
                               &
newByteWow64,
                               
1,
                               
NULL);
        } else { 
// 64bit Process

            
lpContext64bit.ContextFlags CONTEXT_FULL;
            
GetThreadContext(lpProcessInfo.hThread, &lpContext64bit);
            
peb64bit = (DWORD64*)lpContext64bit.Rdx;

            
DWORD64 ImageBaseAddress NULL;
            
ReadProcessMemory(lpProcessInfo.hProcess,
                              &
peb64bit[2],
                              (
LPVOID)&ImageBaseAddress,
                              
sizeof(DWORD64),
                              
NULL);

            
printf("[-] 64bit ImageBase Address     = 0x%p\n"ImageBaseAddress);
            
printf("[-] 64bit EntryPoint Address    = 0x%p\n"lpContext64bit.Rcx);
            
printf("[-] 64bit Process (PEB Address) = 0x%p\n"lpContext64bit.Rdx);

            
uTargetAddress64bit lpContext64bit.Rcx 0x7E;
            
newByte64bit 0x75;

            
WriteProcessMemory(lpProcessInfo.hProcess,
                               (
LPVOID)uTargetAddress64bit,
                               &
newByte64bit,
                               
1,
                               
NULL);

        }

        
ResumeThread(lpProcessInfo.hThread);
        
WaitForSingleObject(lpProcessInfo.hThreadINFINITE);

#else // 32bit Application
        
DWORD32peb32bit;
        
CONTEXT lpContext32bit = {0};

        
DWORD32 uTargetAddress32bit;
        
char newByte32bit;

        
lpContext32bit.ContextFlags CONTEXT_FULL;
        
GetThreadContext(lpProcessInfo.hThread, &lpContext32bit);
        
peb32bit = (DWORD32*)lpContext32bit.Ebx;

        
DWORD32 ImageBaseAddress NULL;
        
ReadProcessMemory(lpProcessInfo.hProcess,
                          &
peb32bit[2],
                          (
LPVOID)&ImageBaseAddress,
                          
sizeof(DWORD32),
                          
NULL);

        
printf("[-] 32bit ImageBase Address     = 0x%08X\n"ImageBaseAddress);
        
printf("[-] 32bit EntryPoint Address    = 0x%08X\n"lpContext32bit.Eax);
        
printf("[-] 32bit Process (PEB Address) = 0x%08X\n"lpContext32bit.Ebx);

        
uTargetAddress32bit lpContext32bit.Eax 0x64;
        
newByte32bit 0x74;

        
WriteProcessMemory(lpProcessInfo.hProcess,
                           (
LPVOID)uTargetAddress32bit,
                           &
newByte32bit,
                           
1,
                           
NULL);

        
ResumeThread(lpProcessInfo.hThread);
        
WaitForSingleObject(lpProcessInfo.hThreadINFINITE);
#endif

    
}

    return 
0;

Attached file contains (source and binary (32bit/64bit and Wow64) for testing purposes)
Attached Files
File Type: rar loader02.rar (7.4 KB, 26 views)
__________________
Computer Forensics
Reply With Quote
The Following 2 Users Gave Reputation+1 to Insid3Code For This Useful Post:
giv (10-21-2015), niculaita (10-21-2015)
The Following 11 Users Say Thank You to Insid3Code For This Useful Post:
b30wulf (10-21-2015), besoeso (10-21-2015), elephant (11-15-2015), giv (10-21-2015), Kjacky (10-21-2015), niculaita (10-21-2015), nikkapedd (10-22-2015), Sn!per X (11-27-2015), uel888 (11-28-2015), zeuscane (10-21-2015)
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Delphi] Check if ASLR is enabled Agmcz Source Code 15 06-11-2018 09:09
[Delphi] Loader shows how to patch PE protected with ASLR Sn!per X Source Code 1 11-28-2015 00:33
How to deal with threads ? bcl25 General Discussion 4 03-29-2003 06:22


All times are GMT +8. The time now is 15:17.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX