Jump to content

new _Mem functions


w0uter
 Share

Recommended Posts

This is how i inject my .dll into a running .exe. Will using auto-it work for this?

#include <windows.h>
#include <TLHELP32.H>
#include <stdio.h>

bool Done;

PROCESSENTRY32 PE32;

char szTarget[] = "war3.exe";
char szPath[256], szDllToInject[256];

int main(int argc, char* argv[], char* envp[])
{
    GetModuleFileName( 0, szPath, sizeof(szPath) ); // Path to our app
    strcpy( szDllToInject, szPath ); // and change last exe to dll
    szDllToInject[ strlen(szPath) - 3] = 'd';
    szDllToInject[ strlen(szPath) - 2] = 'l';
    szDllToInject[ strlen(szPath) - 1] = 'l';

    printf("My uber hack v0.1\n");

    WIN32_FIND_DATA fnd;
    HANDLE DllHnd = FindFirstFile(szDllToInject, &fnd);
    if( DllHnd == INVALID_HANDLE_VALUE )
    {
    printf(".dll not found\n");
    system("pause");
    return 0;
    }

    printf("    Waiting for warcraft(?)\n");
    printf("    to start.....\n");

    HANDLE hSnapshot, hModule, hProcess;
    PE32.dwSize = sizeof(PROCESSENTRY32);

//Now starts a bit copy+paste from injecting article buyaoa posted link to, notice the sleeps so that
//loader won't come a problem if it's on too for longer or you don't want to quit loader after injection
    while(!Done)
    {
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        Process32First(hSnapshot, &PE32);
        while(Process32Next(hSnapshot, &PE32))
        {
            if(strcmp(PE32.szExeFile, szTarget) == 0)
            {
                Sleep(150);

                if(!Done)
                {
                    hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PE32.th32ProcessID);
                    hModule = VirtualAllocEx(hProcess, 0, sizeof(szDllToInject), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                    WriteProcessMemory(hProcess, hModule, (LPVOID)szDllToInject, sizeof(szDllToInject), NULL);
                    CreateRemoteThread(hProcess, NULL, 0, (unsigned long(__stdcall *)(void *))GetProcAddress(GetModuleHandle("kernel32"), "LoadLibraryA"), hModule, 0, NULL );
                    CloseHandle(hProcess);

                return true;
                }
            }
        }
        CloseHandle(hSnapshot);
        Sleep(150);
    }
return true;
}
Link to comment
Share on other sites

Hey im new to the whole posting on forums thing.

w0uter, I have managed to use you function to read an address in a program and it comes back as an ASCII string. (i found out how to convert to decimal)

Then i have tryed serveral ways to write to that address but it just dont seam to do anything. I have tried by changing it in memory with memory editing program (Cheat Engine 5.2) and then i want to write to it back with its old value and observe if it changes. I tried writing back the string that is given by reading the address and it does not change i have also tryed with decimals and hex and no value works.

If you have it working for you would you care to give and example for us or explain "_MemWrite($ah_Mem, $i_Address, $v_Inject)"

$ah_Mem = open process (same as read function)

$i_Address = Address you want to write to

but i dont know what "$v_Inject" is. I assume thats what you want to write but its not working for me.

Also if you where able to code Functions for changing the registers (debugging) this would be very good (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, and the flags CF, PF, AF, ZF, SF, OF)

Cheers

Scrawni

Link to comment
Share on other sites

Hey im new to the whole posting on forums thing.

w0uter, I have managed to use you function to read an address in a program and it comes back as an ASCII string. (i found out how to convert to decimal)

Then i have tryed serveral ways to write to that address but it just dont seam to do anything. I have tried by changing it in memory with memory editing program (Cheat Engine 5.2) and then i want to write to it back with its old value and observe if it changes. I tried writing back the string that is given by reading the address and it does not change i have also tryed with decimals and hex and no value works.

If you have it working for you would you care to give and example for us or explain "_MemWrite($ah_Mem, $i_Address, $v_Inject)"

$ah_Mem = open process (same as read function)

$i_Address = Address you want to write to

but i dont know what "$v_Inject" is. I assume thats what you want to write but its not working for me.

Also if you where able to code Functions for changing the registers (debugging) this would be very good (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, and the flags CF, PF, AF, ZF, SF, OF)

Cheers

Scrawni

Hi and welcome to the forums!

and thanks for your help!

$keymem = _MemOpen($pid)
        $keymem1 = _MemCreate($keymem)
        _MemWrite($keymem, 0x004609F0, chr(guictrlread($keys)))
        MsgBox(262144, guictrlread($keys), ASC(_MemRead($keymem, 0x004609F0)))
        _MemClose($keymem)

now the msgbox says the correct value, but it won't be changed throug _memwrite()......

[font="Verdana"]In work:[list=1][*]InstallIt[*]New version of SpaceWar[/list] [/font]

Link to comment
Share on other sites

ASCII To Decimal Conversion And Back Again

(As seen in SciTE with default colours PS some one should make a script for this would be handy for posting code on forums :o )

#include <string.au3>

$Process = "egprocess.exe"

$Pid = ProcessExists($Process)

$h_open = _MemOpen($pid)

$ASCII = _MemRead($h_open, 0x77D67807,0)

;~ ASCII To Decimal

$ASCII = "*/"

$Temp = _StringReverse($ASCII)

$Temp = _StringToHex($Temp)

$dec = Dec($Temp)

MsgBox(0, "ASCII To Decimal", "ASCII: " & $ASCII & @LF & "Hex: " & $Temp & @LF & "Decimal: " & $dec)

;~ Decimal To ASCII

$dec = 12074

$Hex = Hex($dec,8)

$Temp = _HexToString($Hex)

$ASCII = _StringReverse($Temp)

MsgBox(0, "Decimal To ASCII", "Decimal: " & $dec & @LF & "Hex: " & $Hex & @LF & "ASCII: " & $ASCII)

_________________________________________________________________________________________________

@Analritter

No problems and Cheers NOTE: Your code is too far advanced compared to my level of AutoIt at the moment. But i am in to memory editing with other programs and botting with AutoIt so i would love to have them both rolled into the one program (i sorta understand memory editing and Cheat Engine 5.2 makes it easy)

@w0uter

Would you be able to look into getting the "_MemWrite" Working as this would be a very useful feature. The only feature that i can really use these for at the moment is just like a stats program on the application but no real editing of these values

Edited by Scrawni
Link to comment
Share on other sites

hi,

i'm having trouble with this. i can't seem to read anything.

i've attached the exe file. i can assure you that the file is clean.

Demented.trainme.zip

and here is the code i use:

#include <Memory.au3>

$pid = ProcessExists( "training.exe" )

IF $pid Then
    $mem = _MemOpen( $pid )
    $moneyAddr = _MemRead( $mem, 0x004030a8, 4 )
    ConsoleWrite( "money address: " & $moneyAddr &@cr )
    $money = _MemRead( $mem, $moneyAddr, 4 )
    ConsoleWrite( "money: " & $money &@cr )
Else
    ConsoleWrite( "no such process!" &@cr )
EndIf

i am fairly certain with the address of $moneyAddr i used above. i can read the value in tsearch but i can't get anything with _memread. i've also tried reading some memory addresses of another program but i also get nothing. please advise.

thanks,

-mon.

Link to comment
Share on other sites

that solved my problem, thanks a lot! ;)

np :geek:

but i have a question of my own . . .

This works, and writes 10 to the address.

#include <Array.au3>


$pid = WinGetProcess("prog test")

MsgBox(0,"","PID: " & $pid )

$OpenProccess = _MemOpen($pid)

If @error Then
    MsgBox(0,"error","error opening process.")
    Exit
EndIf


$Read = _MemRead($OpenProccess, 0x41D090, 4)

If IsArray($Read) Then
    _ArrayDisplay($Read, "Read Var" )
EndIf


_MemWrite($OpenProccess, 0x41D090,_MemCreate(10))


_MemClose($OpenProccess)

but this does not:

#include <Array.au3>


$pid = WinGetProcess("prog test")

MsgBox(0,"","PID: " & $pid )

$OpenProccess = _MemOpen($pid)

If @error Then
    MsgBox(0,"error","error opening process.")
    Exit
EndIf


$Read = _MemRead($OpenProccess, 0x41D090, 4)

If IsArray($Read) Then
    _ArrayDisplay($Read, "Read Var" )
EndIf


_MemWrite($OpenProccess, 0x41D090,_MemCreate(2000))


_MemClose($OpenProccess)

Instead of it being 2000 it's some wierd number. Reading is the same. why is this? :o

Thanks, Hallman

Link to comment
Share on other sites

Ok Here is some advise for testing this stuff

Use CE (Cheat Engine 5.2)

Add the address manually or search for it

Add the address for every type of display possible of that varible

i found it to be writing in the one byte form

if you view an address and it one byte its numbers are different to what you would see in 4bytes (4bytes is what most windows programs use)

so you want to write 2000 to the 4bytes but instead it is being written to the byte area (im not really good at explaining i guess you gathered this).

if it is a byte it cant handle numbers over a certian amount.

2000 in 4bytes is the same as -48 as one byte.

although this doesnt explain the first one working properly

i tested and checked with CE 1802 in 4bytes is the same as 10 in bytes

Cheers for the example of how to write but if we could only change what it was writing as (Binary, Byte, 2Byte, 4byte, 8byte, double, float, text, array of bytes)

Hope This Helps

Link to comment
Share on other sites

Ok Here is some advise for testing this stuff

Use CE (Cheat Engine 5.2)

Add the address manually or search for it

Add the address for every type of display possible of that varible

i found it to be writing in the one byte form

if you view an address and it one byte its numbers are different to what you would see in 4bytes (4bytes is what most windows programs use)

so you want to write 2000 to the 4bytes but instead it is being written to the byte area (im not really good at explaining i guess you gathered this).

if it is a byte it cant handle numbers over a certian amount.

2000 in 4bytes is the same as -48 as one byte.

although this doesnt explain the first one working properly

i tested and checked with CE 1802 in 4bytes is the same as 10 in bytes

Cheers for the example of how to write but if we could only change what it was writing as (Binary, Byte, 2Byte, 4byte, 8byte, double, float, text, array of bytes)

Hope This Helps

I think I understand . .. so is there a math formula for converting a number to one byte and vise versa?

I mostly use T-Search but ill try what you said with Cheat Engine. Can't right now since i'm at school :o

Hallman

Link to comment
Share on other sites

I have a memory address for a text value I wanna read. It was found with CE5.2 This is it - 00746046, it doesn't resemble the ones in all of the examples though, such as - 0x41D090. What needs to be done so that I can read this address?

INI TreeViewA bus station is where a bus stops, a train station is where a train stops. Onmy desk I have a work station...
Link to comment
Share on other sites

I have a memory address for a text value I wanna read. It was found with CE5.2 This is it - 00746046, it doesn't resemble the ones in all of the examples though, such as - 0x41D090. What needs to be done so that I can read this address?

I think you need to use 0x746046

btw can someone please post a simple example of how to write a number to an address? Like 2000 or something and also how to read it back so it returns 2000 instead of some other number?

Hallman

Link to comment
Share on other sites

i will look into a way to conver a 4byte into a byte when i get it i will post iot here then you can just enter in that stuff that you want and let autoit do the converting.

I got school so i cant do any thing right now but hopefully i can find out.

If you want try talking to DarkByte hes the guy who coded CE ask on thier forum if you can there is any mathamatical way or something.

Laters

Scrawni

Edited by Scrawni
Link to comment
Share on other sites

How do you use the array with this? I'm gettin' other information then what I need.

This seems to work if the integer it reads is 100 or less.

$pid = WinGetProcess("prog test")

$OpenProccess = _MemOpen($pid)

$Read = _MemRead($OpenProccess, 0x41D090, 4)

MsgBox(0,"_Mem Read","Data Read: " & $Read[0])

_MemClose($OpenProccess)

The byte thing kinda makes things complicated so that's why iv'e only got it to work with small numbers.

:o

Link to comment
Share on other sites

I cannot get this to read properly for the life of me :o

$Process = "EverQuest2.exe"
$Pid = ProcessExists($Process)
$h_open = _MemOpen($pid)
$Read = _MemRead($h_open,0xF4798A,4)
MsgBox(0, "Test Box", "TEst: " & $Read[0])
_MemClose($h_open)

I know for a fact the value of the address at the time of reading is 994, and yet the readout is -3030 every time.

Do you have to convert something? Pay someone? Jump over something?

Any help is much appreciated...

For some more code, here's the functions I have:

#region _Mem()

Func _MemOpen($i_Pid, $i_Access = 0x1F0FFF, $i_Inherit = 0)
    Local $av_Return[2] = [DllOpen('kernel32.dll') ]
    Local $ai_Handle = DllCall($av_Return[0], 'int', 'OpenProcess', 'int', $i_Access, 'int', $i_Inherit, 'int', $i_Pid)
    If @error Then
        DllClose($av_Return[0])
        SetError(1)
        Return 0
    EndIf
    $av_Return[1] = $ai_Handle[0]
    Return $av_Return
EndFunc ;==>_MemOpen

Func _MemRead($ah_Mem, $i_Address, $i_Size = 0)
    If $i_Size = 0 Then
        Local $v_Return = ''
        Local $v_Struct = DllStructCreate('byte[1]')
        Local $v_Ret
        
        While 1
            $v_Ret = DllCall($ah_Mem[0], 'int', 'ReadProcessMemory', 'int', $ah_Mem[1], 'int', $i_Address, 'ptr', DllStructGetPtr($v_Struct), 'int', 1, 'int', '')
            $v_Ret = DllStructGetData($v_Struct, 1)
            If $v_Ret = 0 Then ExitLoop
            $v_Return &= Chr($v_Ret)
            $i_Address += 1
        WEnd
        
    Else
        Local $v_Struct = DllStructCreate('byte[' & $i_Size & ']')
        Local $v_Ret = DllCall($ah_Mem[0], 'int', 'ReadProcessMemory', 'int', $ah_Mem[1], 'int', $i_Address, 'ptr', DllStructGetPtr($v_Struct), 'int', $i_Size, 'int', '')
        Local $v_Return[$v_Ret[4]]
        For $i = 0 To $v_Ret[4] - 1
            $v_Return[$i] = DllStructGetData($v_Struct, 1, $i + 1)
        Next
    EndIf
    Return $v_Return
EndFunc ;==>_MemRead

Func _MemWrite($ah_Mem, $i_Address, $v_Inject)
    Local $av_Call = DllCall($ah_Mem[0], 'int', 'WriteProcessMemory', 'int', $ah_Mem[1], 'int', $i_Address, 'ptr', DllStructGetPtr($v_Inject), 'int', DllStructGetSize($v_Inject), 'int', '')
    Return $av_Call[0]
EndFunc ;==>_MemWrite

Func _MemClose($ah_Mem)
    Local $av_Ret = DllCall($ah_Mem[0], 'int', 'CloseHandle', 'int', $ah_Mem[1])
    DllClose($ah_Mem[0])
    Return $av_Ret[0]
EndFunc ;==>_MemClose

Func _MemCreate($1, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, _
        $16 = 0, $17 = 0, $18 = 0, $19 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $25 = 0, $26 = 0, $27 = 0, $28 = 0, $29 = 0, _
        $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, _
        $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, $49 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, _
        $58 = 0, $59 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0, $67 = 0, $68 = 0, $69 = 0, $70 = 0, $71 = 0, _
        $72 = 0, $73 = 0, $74 = 0, $75 = 0, $76 = 0, $77 = 0, $78 = 0, $79 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0, $85 = 0, _
        $86 = 0, $87 = 0, $88 = 0, $89 = 0, $90 = 0, $91 = 0, $92 = 0, $93 = 0, $94 = 0, $95 = 0, $96 = 0, $97 = 0, $98 = 0, $99 = 0)
    If IsString($1) Then
        $1 = StringSplit($1, '')
        Local $v_Helper = DllStructCreate('byte[' & UBound($1) & ']')
        For $i = 1 To UBound($1) - 1
            DllStructSetData($v_Helper, 1, Asc($1[$i]), $i)
        Next
    Else
        Local $v_Helper = DllStructCreate('byte[' & @NumParams & ']')
        For $i = 1 To @NumParams
            DllStructSetData($v_Helper, 1, Eval($i), $i)
        Next
    EndIf
    Return $v_Helper
EndFunc ;==>_MemCreate

Func _MemRev($v_DWORD)
    If UBound($v_DWORD) = 4 Then Return '0x' & Hex($v_DWORD[3], 2) & Hex($v_DWORD[2], 2) & Hex($v_DWORD[1], 2) & Hex($v_DWORD[0], 2)
    Local $v_Ret[4] = ['0x' & StringMid(Hex($v_DWORD, 8), 7, 2), '0x' & StringMid(Hex($v_DWORD, 8), 5, 2), '0x' & StringMid(Hex($v_DWORD, 8), 3, 2), '0x' & StringMid(Hex($v_DWORD, 8), 1, 2) ]
    Return $v_Ret
EndFunc ;==>_MemRev

Func _MemAlloc($ah_Mem, $i_Size, $i_Address = 0, $i_AT = 4096, $i_Protect = 0x40)
    Switch @OSVersion
        Case "WIN_ME", "WIN_98", "WIN_95"
            $av_Alloc = DllCall($ah_Mem[0], 'int', 'VirtualAlloc', 'int', $i_Address, 'int', $i_Size, 'int', BitOR($i_AT, 0x8000000), 'int', $i_Protect)
        Case Else
            $av_Alloc = DllCall($ah_Mem[0], 'int', 'VirtualAllocEx', 'int', $ah_Mem[1], 'int', $i_Address, 'int', $i_Size, 'int', $i_AT, 'int', $i_Protect)
    EndSwitch
    Return $av_Alloc[0]
EndFunc ;==>_MemAlloc

Func _MemFree($ah_Mem, $i_Address)
    Switch @OSVersion
        Case "WIN_ME", "WIN_98", "WIN_95"
            $av_Free = DllCall($ah_Mem[0], 'int', 'VirtualFree', 'int', $i_Address, 'int', 0, 'int', 0x8000)
        Case Else
            $av_Free = DllCall($ah_Mem[0], 'int', 'VirtualFreeEx', 'int', $ah_Mem[1], 'int', $i_Address, 'int', 0, 'int', 0x8000)
    EndSwitch
    Return $av_Free[0]
EndFunc ;==>_MemFree

Func _MemText($ah_Mem, $s_Text)
    Local $i_Size = StringLen($s_Text) + 1
    Local $i_Addr = _MemAlloc($ah_Mem, $i_Size)
    _MemWrite($ah_Mem, $i_Addr, _MemCreate($s_Text))
    Return $i_Addr
EndFunc ;==>_MemText

#endregion

I don't #include this, it's straight in my code... I Beta Compile through SCiTE, then run it.

Ha, I haven't been on these forums since... 2006, almost. Behold, my legacy signature:My AutoIt idol is Valuater. You know you love him, too.My Stuff: D&D AGoT Tools Suite
Link to comment
Share on other sites

I cannot get this to read properly for the life of me :o

...

Like i said in my last post

This seems to work if the integer it reads is 100 or less.

it's a problem with the bytes.

The number your getting is the one byte form. You need to convert it to 4 bytes if the number is larger than 100.

Hallman

Edited by Hallman
Link to comment
Share on other sites

Like i said in my last post

it's a problem with the bytes.

The number your getting is the one byte form. You need to convert it to 4 bytes if the number is larger than 100.

Hallman

Isn't that what the 4 in this code:

$Read = _MemRead($h_open,0xF4798A,4)

Does?

And the value may fall under 100... How would I compensate for this on the fly?

Edit:

Oh yeah, and when I subtract the 4 I get errors about the value not being an array (The messagebox piece, specifically "$Read[0]")

Edited by JoshDB
Ha, I haven't been on these forums since... 2006, almost. Behold, my legacy signature:My AutoIt idol is Valuater. You know you love him, too.My Stuff: D&D AGoT Tools Suite
Link to comment
Share on other sites

Isn't that what the 4 in this code:

$Read = _MemRead($h_open,0xF4798A,4)

Does?

And the value may fall under 100... How would I compensate for this on the fly?

If you check you see that the returned array has the same amount of elements as the number of bytes you wrote ( which is 4 ). All the other elements exept 0 have nothing in them when i read like 50. I dont understand how it works. :o Maybe you can figure it out?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...