Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Injected message box
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Mon Sep 27, 2010 1:10 pm    Post subject: Injected message box Reply with quote

I'm injecting some code into another process using VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. I've tested this with some infinite loop code (a few nops and a jmp) which works perfectly, creating a thread that eats up 100% of my CPU time on one core.

What I'd like to do is call an API such as MessageBoxA from the remote process, but because of ASLR and the fact that the remote process may not be the same each time (I'm injecting into multiple versions of the same process) I'm having trouble detecting the address of such APIs so that they can be called from my injected code.

I'm guessing I'd need to identify the location of the IAT, then scan it for the address of the API that I want to call, somehow identifying it in the list. Any ideas how I'd go about this?

_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Mon Sep 27, 2010 1:34 pm    Post subject: Reply with quote

You could do it through the IAT of the remote process, or use CreateToolhelp32Snapshot to get a list of remote modules.
If you get the correct address of 'GetProcAddress' and put it in the code stub then you can get the other addresses with the code from there.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Sep 27, 2010 3:10 pm    Post subject: Reply with quote

You can obtain the API (MessageBoxA) address inside your current application and inject a block to call the address. You can

Heres a small example I wrote for someone a while back:

Code:
//
// Code Injection Example
//
// Coded by: atom0s
// Coded on: Oct. 08, 2009
//

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#include <tlhelp32.h>

/*
 * The below byte array converts to a 'similar' look of the following
 * C/C++ code. This has been converted to the asm bytes for injection.
 *
void HelloWorld( void )
{
    char* szMessage = "Hello World!";
    char* szCaption    = "Hello!";

    HMODULE hModule        = LoadLibraryA( "user32.dll" );
    FARPROC fFuncProc    = GetProcAddress( hModule, "MessageBoxA" );

    ( ( int ( WINAPI *)( HWND, LPCSTR, LPCSTR, UINT ) ) fFuncProc )( 0, szMessage, szCaption, 0 );

} */
BYTE btFunction[] = {

    0x55,
    0x8B, 0xEC,
    0x83, 0xEC, 0x10,
    0xC7, 0x45, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,     // Replace String #1
    0xC7, 0x45, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF,     // Replace String #2
    0x68, 0xFF, 0xFF, 0xFF, 0xFF,                 // Replace String #3
    0xE8, 0xFF, 0xFF, 0xFF, 0xFF,                // LoadLibraryA
    0x89, 0x45, 0xF4,
    0x68, 0xFF, 0xFF, 0xFF, 0xFF,                // Replace String #4
    0x8B, 0x45, 0xF4,
    0x50,
    0xE8, 0xFF, 0xFF, 0xFF, 0xFF,                // GetProcAddress
    0x89, 0x45, 0xF8,
    0x6A, 0x00,
    0x8B, 0x4D, 0xFC,
    0x51,
    0x8B, 0x55, 0xF0,
    0x52,
    0x6A, 0x00,
    0xFF, 0x55, 0xF8,
    0x8B, 0xE5,
    0x5D,
    0xC3

};


bool InjectCode( DWORD dwProcId )
{
    /*
     * Our various needed strings for our messagebox
     * function to properly work.
     */

    char* szModule        = "user32.dll";
    char* szFunction    = "MessageBoxA";
    char* szMessage        = "Hello world!";
    char* szCaption        = "Hello!";

    /*
     * Open our process with proper access so we can
     * do various memory operations and such.
     */

    HANDLE hHandle = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, 0, dwProcId );
    if( hHandle == INVALID_HANDLE_VALUE )
        return false;

    /*
     * Allocate memory for our strings and function,
     * each string has it's own memory block.
     */

    LPVOID lpString1    = VirtualAllocEx( hHandle, 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    LPVOID lpString2    = VirtualAllocEx( hHandle, 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    LPVOID lpString3    = VirtualAllocEx( hHandle, 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    LPVOID lpString4    = VirtualAllocEx( hHandle, 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    LPVOID lpFunction    = VirtualAllocEx( hHandle, 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

    if( lpString1 == NULL || lpString2 == NULL || lpString3 == NULL || lpString4 == NULL || lpFunction == NULL ) {
        CloseHandle( hHandle );
        return false;
    }

    /*
     * Write our strings to their memory.
     */

    WriteProcessMemory( hHandle, lpString1, szMessage, strlen( szMessage ), 0 );
    WriteProcessMemory( hHandle, lpString2, szCaption, strlen( szCaption ), 0 );
    WriteProcessMemory( hHandle, lpString3, szModule, strlen( szModule ), 0 );
    WriteProcessMemory( hHandle, lpString4, szFunction, strlen( szFunction ), 0 );

    /*
     * Fix our functions string addresses before writing
     * it to the process memory. (Faster this way.)
     */

    memcpy( (LPVOID)( (DWORD)&btFunction + 0x09 ), &lpString1, 4 );
    memcpy( (LPVOID)( (DWORD)&btFunction + 0x10 ), &lpString2, 4 );
    memcpy( (LPVOID)( (DWORD)&btFunction + 0x15 ), &lpString3, 4 );
    memcpy( (LPVOID)( (DWORD)&btFunction + 0x22 ), &lpString4, 4 );

    /*
     * Fix the API calls inside our function as well.
     */

    DWORD dwLoadLibrary = ( ( (DWORD)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "LoadLibraryA" ) - ( (DWORD)lpFunction + 0x1A ) ) - 4 );
    DWORD dwGetProcAddr = ( ( (DWORD)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetProcAddress" ) - ( (DWORD)lpFunction + 0x2B ) ) - 4 );

    memcpy( (LPVOID)( (DWORD)&btFunction + 0x1A ), &dwLoadLibrary, 4 );
    memcpy( (LPVOID)( (DWORD)&btFunction + 0x2B ), &dwGetProcAddr, 4 );


    /*
     * Write our function to the last memory block.
     */

    WriteProcessMemory( hHandle, lpFunction, &btFunction, sizeof( btFunction ), 0 );

    /*
     * Create a thread and call the function.
     */

    HANDLE hThread = CreateRemoteThread( hHandle, 0, 0, (LPTHREAD_START_ROUTINE) lpFunction, 0, 0, 0 );
    if( hThread == NULL ) {
        CloseHandle( hHandle );
        return false;
    }

    return true;
}

int __cdecl main( int argc, TCHAR* argv[] )
{

    PROCESSENTRY32    pe32        = { sizeof( PROCESSENTRY32 ) };
    HANDLE            hSnapshot    = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

    if( hSnapshot == INVALID_HANDLE_VALUE )
        return 0;

    if( ! Process32First( hSnapshot, &pe32 ) ) {
        CloseHandle( hSnapshot );
        return 0;
    }

    do {
        if( _tcsicmp( _T( "winmine.exe" ), pe32.szExeFile ) == 0 ) {

            CloseHandle( hSnapshot );
            InjectCode( pe32.th32ProcessID );
            return 0;

        }
    } while( Process32Next( hSnapshot, &pe32 ) );

    CloseHandle( hSnapshot );

    return 0;
}

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Mon Sep 27, 2010 3:21 pm    Post subject: Reply with quote

I can get the base address of the module without using GetProcAddress, since I'm coding in .NET and the Process class provides a list of loaded modules. However, I don't know how to get the relative address from base to the exported function I want. Any ideas on how to do this?
_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Sep 27, 2010 3:29 pm    Post subject: Reply with quote

Calculate it based on where your allocation is and where you are writing it inside your 'cave'.

Your VirtualAllocEx call will return the base of your cave.

API Address - Cave Base + Offset in cave - 4

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Mon Sep 27, 2010 3:34 pm    Post subject: Reply with quote

I know how to calculate that offset, but it's the API address I need to find. I know the base address of the module, but not the actual address of the API. I can find the address of the ASCII names in the DLL image, but I don't know how they map to the address.
_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Mon Sep 27, 2010 3:52 pm    Post subject: Reply with quote

Burningmace wrote:
I know how to calculate that offset, but it's the API address I need to find. I know the base address of the module, but not the actual address of the API. I can find the address of the ASCII names in the DLL image, but I don't know how they map to the address.

If you have the address of the API in your own process (Using GetProcAddress), and the module base address of the module in your own process, then calculate the difference between the remote module base and the 'local' module base, and add that difference to the API address in your own process.
Back to top
View user's profile Send private message
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Mon Sep 27, 2010 3:58 pm    Post subject: Reply with quote

I'm coding this in .NET, so GetProcAddress won't work Sad
_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Sep 27, 2010 5:07 pm    Post subject: Reply with quote

Burningmace wrote:
I'm coding this in .NET, so GetProcAddress won't work Sad


Just import GetProcAddress and GetModuleHandle and invoke them:
Code:

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        static extern UIntPtr GetProcAddress(IntPtr hModule, string procName);

        IntPtr lpUser32 = GetModuleHandle("user32.dll");
        UIntPtr uiMsgBoxA = GetProcAddress(lpUser32, "MessageBoxA");


_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Mon Sep 27, 2010 6:07 pm    Post subject: Reply with quote

The above suggestions work, but they're all kind of a pain to implement. Writing a native DLL for injection is just so much easier.

Otherwise, I'd probably look to inject a script engine (lua, underc, perl, python, ruby, whatever) if the target app is running on a system that either already has the script engine/libraries installed or can be made to install them. Then you can wrap the processes of creating remote memory for a script, writing the script to remote memory, asking the interpreter to execute the script and freeing the memory in a trivially simple function. All of the scripting languages I can think of include dynaloading and win32 api support.

Lastly, there are a few just-in-time compilers. If you go down the path you're heading, I /highly/ recommend looking into them. The process of writing and patching shell-code (i.e., the replace-strings in Wicca's btFunction) is ugly, error-prone, and very difficult code to maintain.

Cheers,
adude
Back to top
View user's profile Send private message
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Mon Sep 27, 2010 7:09 pm    Post subject: Reply with quote

Wiccaan wrote:
Just import GetProcAddress and GetModuleHandle and invoke them


Hadn't thought of the GetModuleHandle approach, I'll give it a go. I'm so glad ASLR doesn't switch the module load offset per-process Shocked

_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Tue Sep 28, 2010 12:09 am    Post subject: Reply with quote

Burningmace wrote:
Wiccaan wrote:
Just import GetProcAddress and GetModuleHandle and invoke them


Hadn't thought of the GetModuleHandle approach, I'll give it a go. I'm so glad ASLR doesn't switch the module load offset per-process :shock:


AFAIK, it /does/ (with the exception of kernel32). I think that it was implied that you'd load the dll into your own process, call getmodulehandle to get the base address of the dll, call getprocaddress to get the offset of the function you wanna' map out in the target process, and apply the difference of the two to the base address of the same module's base address inside the target process (which you find w/ the tlhelp calls). It's arguably easier to just inject code to call getprocaddress directly from within the target process.
Back to top
View user's profile Send private message
angelababy
Newbie cheater
Reputation: -1

Joined: 01 Aug 2010
Posts: 22

PostPosted: Tue Sep 28, 2010 2:18 am    Post subject: Reply with quote

Then you can wrap the processes of creating remote memory for a script, writing the script to remote memory, asking the interpreter to execute the script and freeing the memory in a trivially simple function.
_________________
Welcome to my paintings website -
Back to top
View user's profile Send private message
Polynomial
Grandmaster Cheater
Reputation: 5

Joined: 17 Feb 2008
Posts: 524
Location: Inside the Intel CET shadow stack

PostPosted: Tue Sep 28, 2010 6:15 am    Post subject: Reply with quote

justa_dude wrote:
Burningmace wrote:
I'm so glad ASLR doesn't switch the module load offset per-process Shocked


AFAIK, it /does/ (with the exception of kernel32). I think that it was implied that you'd load the dll into your own process, call getmodulehandle to get the base address of the dll, call getprocaddress to get the offset of the function you wanna' map out in the target process, and apply the difference of the two to the base address of the same module's base address inside the target process (which you find w/ the tlhelp calls). It's arguably easier to just inject code to call getprocaddress directly from within the target process.


The ASLR bias is set at boot during phase 1 (Phase1InitializationDiscard), so it only changes per boot. I think what you're describing is Library Load Order Randomization, a function of ASLR which changes the actual placement of the module in memory in relation to other DLLs. This again is determined by the ASLR bias so it's the same between processes. When you reboot it all changes because the ASLR bias is different.

_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time.
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Tue Sep 28, 2010 8:25 am    Post subject: Reply with quote

It may not be a function of ASLR, but it is a fact that dlls are not always mapped into the same virtual address space from one process to the next. It is also a fact that getmodulehandle is only intended to retrieve information related to the calling process.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites