Jump to content

Executing raw machine code


Lazycat
 Share

Recommended Posts

  • Replies 47
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

You can 'poke' code using WriteProcessMemory... Just need to write the bytes of the opcodes and etc to wherever you need them to be written.

Poke 401384 90 90 90 90 90

Can't do that with Nomad Memory. How would I do what you said?

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

_MemoryWrite(0x401384, $av_Handle, 0x90, "byte")

I believe that will do it, give it a try.

Failed.

(Tested using the TSearch, programme test)

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

  • 2 months later...

I think it would be relatively easy to use HLA for this. There are very good resources on that site to let newcomers start learning assembly, and more experienced folks should enjoy the utilities there. Compilers, helpful forums, and lots of examples for both linux and win32.

Inserting raw machine code will be much easier if it's done in a manner tailored to AutoIt, so I'm going to see what can be done to make this a little more friendly towards beginners (seeing as I'm pretty much in that category myself.)

Very cool!

Link to comment
Share on other sites

  • 3 weeks later...

it simply dont work

the script get an error and returns -1073741819

i found that it occurs at the first dllcall line, to fill the lookup table

EDIT: I'm using win xp SP2

Edited by Tulio
Link to comment
Share on other sites

  • Moderators

it simply dont work

the script get an error and returns -1073741819

i found that it occurs at the first dllcall line, to fill the lookup table

EDIT: I'm using win xp SP2

Here's a question... how can you say "it simply don't work", when so many it is working for? Logically it would tell you the error is on your end then.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

IT DOESNT WORK! I MADE A PROGRAM TO PRINT REAL $100 BILLS AND THIS ISNT MAKING IT WORK!

;P

Give us exactly what you're trying to do, and we'll tell you either how to go about it, or if it's even possible. It's usually something simple that isn't immediately apparent to you.

Link to comment
Share on other sites

  • 2 weeks later...

Could someone put together a simpler example that takes two numbers and adds them?

I'd love to put this together into UDF form, but I'm unfamiliar with some of the concepts being used here.

Link to comment
Share on other sites

This code looks ridiculously complex, then again I only dared glance at ASM code once in my life. A UDF would be cool jrowe, wish I could help heh, good luck.

EDIT: Just ran on a 781MB file - 28585ms (28.5 secs).. that's pretty awesome o.O.

Edited by dandymcgee

- Dan [Website]

Link to comment
Share on other sites

The concepts are simple enough, but the implementation is specific to the example, the CRC32 function. I can do DLLs in ASM relatively easily... theres a ton of examples out there, and I have an ASM to binary conversion tool which makes getting the machine code really easy.

Link to comment
Share on other sites

That's the thing though: each function is different. There isn't really any way to make this into a UDF in and of itself, as the resulting functions (and any parameters they may take) depend entirely on the original function from which the raw code was pulled. At best, this is a method or a technique for creating UDFs more than anything "UDF-able." The only real commonality between these raw machine code based functions is that they all call CallWindowProc at some point or another to do the actual processing.

Take a look at Ward's UDFs for examples of how different each function can be.

What needs to be done for this to become more prevalent is for there to be a tutorial/automator to help people find their way around it all.

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

Gonna take a stab at simplifying the existing example...

$str = FileRead(@ScriptDir & "\file.dat")
$timer = TimerInit()
$crc2 = Hex(FastCRC32($str), 8)
$timer1 = TimerDiff($timer)

Sets $str equal to file.dat, sets the timer, converts the result returned by running FastCRC32 on $str, limiting result to 8 digits, checks the clock again and returns the difference between the clock and the original marked time.

Nothing magical yet.

MsgBox (0, "Result", $crc2 & " in " & Round($timer1) & " ms")

Displays a msgbox displaying the results of operations so far.

Next we encounter the function definition:

Func FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)

This tells us that the Function takes two parameters, one of which is optional, the default set to 0xFFFFFFFF. $vBuffer is the data which the function parses in order to return a result.

Local $nLen, $vTemp

Two variables set for use only within the function.

If DllStructGetSize($vBuffer) = 0 Then; String passed
        If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
        Else
            $nLen = StringLen($vBuffer)
        EndIf
        $vTemp = DllStructCreate("byte[" & $nLen & "]")
        DllStructSetData($vTemp, 1, $vBuffer)
        $vBuffer = $vTemp
    EndIf

Tests the size of the passed data, $vBuffer, as a dll struct. If it's astring, it tests string length. If it's binary, it tests binary length. Length of the dll struct is set to the variable $nLen.

$vTemp is created as a C/C++ style structure (this is actually fairly meaningless to me, if someone would care to expound on the topic a bit, I'd be obliged.)

From what I can see, $vTemp is initialized to be read in byte format, of the length $nLen.

At index 1 in the DLL Struct $vTemp, the actual data from $vBuffer is stored.

$vBuffer is then set equal to $vTemp.

The Function formats the original data to be used by a DLL call, without losing any of the original data. I'm assuming that the formatting has to do with loading something in memory, as opposed to having it stored on the disk.

Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072

DB5E8B4510F7D05DC3"

Two relatively simple machine code hex strings, representing... what?

The code that was in the attachment from the OP is as follows:

CODE

typedef unsigned long uint;

void CRC32_Init(uint* table) { // uint table[256]

uint i, j, poly = 0xEDB88320, CRC;

for(i = 0; i < 256; i++) {

CRC = i;

for(j = 0; j < 8; j++)

if(CRC & 1)

CRC = (CRC >> 1) ^ poly;

else

CRC >>= 1;

table = CRC;

}

}

uint CRC32(unsigned char* buffer, uint len, uint crc32val, uint* table) { // init: crc32val = 0xFFFFFFFF

uint i;

for (i = 0; i < len; i++)

crc32val = table[(crc32val ^ buffer) & 255] ^ (crc32val >> 8);

return ~crc32val;

}

I don't know how or where data is being passed, yet, so I'm gonna slog onward.

Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)

2 More DLL Structs are created in a similar fashion to the first, by taking the lengths and then setting the data from $CRC32Init and $CRC32Exec.

From the names we can determine that $CRC32Init is the initialization of the function, and $CRC32Exec should be what executes the whole shebang.

Local $CRC32LookupTable = DllStructCreate("int["& 256 &"]")

Dunno what this is here for. Changing 256 to 1, 2, 3, 512, 128, and 47 hasn't changed anything for me.

DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
                                                   "ptr", DllStructGetPtr($CRC32LookupTable), _
                                                   "int", 0, _
                                                   "int", 0, _
                                                   "int", 0)

This opens user32.dll, asks for a return type of int, and calls for the function CallWindowProc. The type of call it's making is 'ptr', and the parameter passed is the pointer to one of the Dll Structs created earlier, $CRC32InitCode.

Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
                                                                 "ptr", DllStructGetPtr($vBuffer), _
                                                                 "uint", DllStructGetSize($vBuffer), _
                                                                 "uint", $nCRC32, _
                                                                 "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret[0]

The same is done for $CRC32ExecCode, but is set to the value of $ret, which is then returned by the function. $CRC32ExecCode is where $vBuffer is actually passed to a DllCall.

So, my questions are:

What is the purpose of $CRC32LookupTable and $CRC32Init?

Link to comment
Share on other sites

$vTemp is created as a C/C++ style structure (this is actually fairly meaningless to me, if someone would care to expound on the topic a bit, I'd be obliged.)

From what I can see, $vTemp is initialized to be read in byte format, of the length $nLen.

This needs to be done because the variable storing the binary data read from the file is not stored in a way directly accessible to the function (it's stored in an AutoIt variant object, which has a bit of fluff more than the bare data). By creating a struct, the pointer to the raw data that the machine-code function is expecting can be passed to it.

From what I gather (I'm no expert on the subject in any way -- speculation here), $CRC32InitCode initializes the CRC32 lookup table, $CRC32ExecCode performs the actual calculation using the file data and the initialized lookup table. By writing them into a struct, you write them into memory raw, and can get the raw pointer to them, which CallWindowProc can then call/execute as a real function (because, after all, functions are just more bits of data stored in memory, just interpreted differently from plain ol' binary data).

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

So it's loaded into memory with AutoIt by setting the $str variable to whatever the data is that's being read, so it's actually been moved to the RAM, and when the pointer is called, it's a way of telling the function where the address is of the data it's supposed to be working with, instead of actually passing the data itself to the function?

And the 'c/c++ style structure' simply means a format within which pointers can be used to reference data?

Neat.

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...