Chapter4

OllyMachine API

When I designing the Virtual Machine, I strongly felt that the basic instructions could not accomplish the high-level operations. So, I wrote some libraries which called API for programmers.

4.1  Hello World!

Following Dennis Ritchie's example, it has become typical to begin learning a new programming language by creating the simple "Hello, World!" program. We aren't going to sidestep this tradition. Let's see a "Hello, World!" in OllyMachine:

// Method 1:
lds reg01, "Hello World!"
push reg01
msg

// Method 2:
push "Hello World!"
msg

// Method 3:
invoke msg, "Hello World!"

4.2  Invoking Method

The invoking method I designed is like x86 machine - use stack to pass parameters. Let's take the "Hello, World!" for example:

lds reg01, "Hello World!"
push reg01
msg

// another way:
push "Hello World!"
msg

"msg" is an API to print a string. It has only one parameter, this parameter must be a register, storing string's offset address, or a quote string.

Aha, when invoking APIs, if there're parameters, we must use PUSH instruction to push the parameters from right to left, then calling the API's name. When the API runs over, stack will balance automatically, we needn't deal with it.

So what the hell is "push the parameters from right to left"? Let's make an example:

push 16
push 0xFF
PrintNum

This program's result is popping a MessageBox to show the hex 0xFF.

We invoked API: PrintNum, it has two parameters, its prototype is:

PrintNum Value, Base

If we push the parameters from right to left, then the "Base" should be first, later is "Value". We can see, in this example, we're surely push "16"(Base) first, then the "0xFF"(Value), and finally the API's name, it's match case with our invoking method.

4.3  Handy Invoking Method

From version 0.11, we could use INVOKE macro for API invoking, for example:

push 16
push 0xFF
PrintNum

invoke PrintNum, 0xFF, 16

Just like the same with MASM32's INVOKE macro, is it more easier to use? ^_^

4.4  Return Value

Sometimes, we need to know what the API returns us, for example:

lds reg01, "Are you sure?"
push reg01
msgyn

// another way:
push "Are you sure?"
msgyn

// yet another way:
invoke msgyn, "Are you sure?"

The API "MsgYN" will show a dialog to let the user choose "Y/N", and we must know what the user chosed to decided what to do next.

In OllyMachine Virtual Machine, all API functions follow this rule:

If the API has return value, it will be stored in register REG00.

In the example above, if user chosed "Y", then REG00 will be 1 (means success), if user chosed "N", then REG00 will be 0 (means fail).

4.5  Basic Input Output API

OllyMachine Virtual Machine supports some input & output APIs:

4.5.1  MSG

Prototype:

MSG message

Explanation:

MSG pops up a MessageBox to disaplay a message.

Parameters:

Return Value:

None

Example:

invoke msg, reg01, "Hello World!"

4.5.2  MSGYN

Prototype:

MSGYN message

Explanation:

MSGYN pops up a MessageBox to display a message, and request user to input Y/N

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke msgyn, "Are you sure to continue?"

cmp reg00, 1
je Continue
halt
Continue:
// ...

4.5.3  PrintNum

Prototype:

PrintNum Value, Base

Explanation:

PrintNum use Base radix to calculate Value, and display the result in a MessageBox

Parameters:

Return Value:

None

Example:

invoke PrintNum, 0x100, 16

4.5.4  PrintBuf

Prototype:

PrintBuf address, len

Explanation:

PrintBuf pops up a MessageBox to display len bytes starting at address.

Parameters:

Return Value:

None

Example:

invoke PrintBuf, eip, 10

4.5.5  PrintBufToDump

Prototype:

PrintBufToDump address

Explanation:

PrintBufToDump prints the buffer starting at address to dump window.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke PrintBufToDump, eip

4.5.6  PrintBufToNewDump

Prototype:

PrintBufToNewDump title, address, len

Explanation:

PrintBufToNewDump firstly creates a new dump window, which has a title,
then prints the buffer starting at address, length is len, to the new dump window.

Parameters:

Return Value:

Succeeds: HWND of new dump window
Fails: 0

Example:

invoke PrintBufToNewDump, "New Dump Window", eip, 0x100

4.5.7  UpdateDumpBuf

Prototype:

UpdateDumpBuf hwnd, address, len

Explanation:

Update buffer which starting at address, length is len, to an existing dump window.
Usually, the dump window's hwnd is getted from PrintBufToNewDump's return value.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// Create a new dump window:
invoke PrintBufToNewDump, "New Dump Window", eip, 0x100
// Save its hwnd:
mov reg01, reg00
//...
// Update it:
invoke UpdateDumpBuf, reg01, eip, 0x200

4.5.8  InputText

Prototype:

InputText title

Explanation:

InputText pop up a dialog to let user input a string.
Attention: title's length can't larger than 256 bytes,
           user's inputed string can't larger than 4096 bytes.

Parameters:

Return Value:

Succeeds: 1
Fails: 0 (User pressed CANCEL button, or user's inputed string larger than 4096 bytes.)

If succeed, user's inputed string could be access by FreeBufferReg,
the size of the string is stored in FreeBufferSizeReg.

Example:

// ask user's name
invoke InputText, "Please input your name"

// print user's name
invoke msg, FreeBufferReg

4.5.9  InputHexLong

Prototype:

InputHexLong value, title

Explanation:

InputHexLong pops up a dialog to let user input a hex number, which is initialized to value.
Attention: title can't larget than 256 bytes.

Parameters:

Return Value:

Succeeds: store user's inputed hex number in reg00
Fails: if user pressed CANCEL button, store initialized value to reg00

Example:

invoke InputHexLong, eip, "Please input EIP"
invoke PrintNum, reg00, 16

4.6  Memory Process API

4.6.1  ReadMemLong

Prototype:

ReadMemLong address, len

Explanation:

ReadMemLong reads len bytes starting at address.
If len < 1, it will be set to 1, if len > 4, it will be set to 4.

Parameters:

Return Value:

Succeeds: len bytes read
Fails: -1

Example:

invoke ReadMemLong, eip, 4

4.6.2  WriteMemLong

Prototype:

WriteMemLong address, valua, len

Explanation:

WriteMemLong writes len bytes value to memory address starting at address.
If len < 1, it will be set to 1, if len > 4, it will be set to 4.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke WriteMemLong, eip, 0x9090, 2

4.6.3  WriteMemHexes

Prototype:

WriteMemHexes address, hexes

Explanation:

Write hexes to address.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke WriteMemHexes, eip, "e800000000"

4.6.4  ReadFileIntoMem

Prototype:

ReadFileIntoMem filename, addrbase, filesize

Explanation:

Read file(filename) into memory, allocated memory for it.
The starting address of memory which allocated for file is stored in addrbase,
file's size is in filesize.
ATTENTION! MUST use VirtualFreeEx to free the memory! Or it will cause memory leak!

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// Read the file into the memory
// reg01 = memory starting address
// reg02 = filesize
invoke ReadFileIntoMem, "test.exe", indexof reg01, indexof reg02

// Print the file contents byte by byte
mov reg10, reg01
read_file_contents:
    invoke ReadMemLong, reg10, 1
    invoke PrintNum, reg00, 16
    inc reg10
    dec reg02
    cmp reg02, 0
    jne read_file_contents

// Remember to free the memory!!!
invoke VirtualFreeEx, indexof reg01

4.6.5  DumpMem

Prototype:

DumpMem address, len, filename

Explanation:

Dumps memory of specified size from specified address to specified file

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// example1:
invoke DumpMem, eip, 10, "c:\test.bin"

// example2:
invoke InputText, "Please input filename"
invoke DumpMem, eip, 10, FreeBufferReg

4.6.6  DumpMemAppend

Prototype:

DumpMemAppend address, len, filename

Explanation:

Dumps memory of specified size from specified address to specified file,
appending to that file if it exists.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// example1:
invoke DumpMemAppend, eip, 10, "c:\test.bin"

// example2:
invoke InputText, "Please input filename"
invoke DumpMemAppend, eip, 10, FreeBufferReg

4.6.7  DumpAsPE

Prototype:

DumpAsPE filename, eip

Explanation:

Dumps the executable to file with specified name.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke DumpAsPE, "c:\test.exe", eip

4.7  Search and Replace API

4.7.1  FindOpcode

Prototype:

FindOpcode address, opcode

Explanation:

Finds opcode starting at address for an instruction that begins with the specified bytes.

Parameters:

Return Value:

Succeeds: address found
Fails: -1

Example:

invoke FindOpcode, eip, 0x90

4.7.2  Find

Prototype:

Find address, code

Explanation:

Finds code starting at address for an instruction that begins with the specified bytes.
Supports wildcard "??". One "??" for one byte.

Parameters:

Return Value:

Succeeds: address found
Fails: -1

Example:

invoke Find, eip, "e8????????"   // find a CALL XXXXXXXX
invoke PrintNum, reg00, 16

// find:
//   CALL XXXXXXXX
//   PUSH 0
invoke Find, eip, "e8????????6a00"
invoke PrintNum, reg00, 16

4.7.3  ReverseFind

Prototype:

ReverseFind address, code

Explanation:

Reverse finds code starting at address for an instruction that begins
with the specified bytes. Supports wildcard "??". One "??" for one byte.

Parameters:

Return Value:

Succeeds: address found
Fails: -1

Example:

// Reverse find a CALL XXXXXXXX
invoke ReverseFind, eip, "e8????????"
invoke PrintNum, reg00, 16

// Reverse find:
//   CALL XXXXXXXX
//   PUSH 0
invoke ReverseFind, eip, "e8????????6a00"
invoke PrintNum, reg00, 16

4.7.4  Search

Prototype:

Search address, code

Explanation:

Searches code starting at address for an instruction that begins with the specified bytes.
Supports wildcard "??". One "??" for one byte.

The differences between "Search" and "Find" are, "Search" will not search from a starting
address of a opcode. For example:

004010DC 55             PUSH EBP
004010DD 8BEC           MOV EBP,ESP
004010DF 6A FF          PUSH -1

if we use invoke Find, eip, "EC6AFF", then will find nothing, return -1.
if we use invoke Search, eip, "EC6AFF", then will return 004010DE.

Parameters:

Return Value:

Succeeds: address found
Fails: -1

Example:

// Search a CALL XXXXXXXX
invoke Search, eip, "e8????????"
invoke PrintNum, reg00, 16

// Search:
//   CALL XXXXXXXX
//   PUSH 0
invoke Search, eip, "e8????????6a00"
invoke PrintNum, reg00, 16

4.7.5  ReverseSearch

Prototype:

ReverseSearch address, code

Explanation:

Searches code starting at address for an instruction that begins with the specified bytes.
Supports wildcard "??". One "??" for one byte.

The differences between "ReverseSearch" and "ReverseFind" are,
"ReverseSearch" will not search from a starting address of a opcode.
For example:

004010DC 55             PUSH EBP
004010DD 8BEC           MOV EBP,ESP
004010DF 6A FF          PUSH -1

if we use invoke ReverseFind, eip, "EC6AFF", then will find nothing, return -1.
if we use invoke ReverseSearch, eip, "EC6AFF", then will return 004010DE.

Parameters:

Return Value:

Succeeds: address found
Fails: -1

Example:

// Reverse search a CALL XXXXXXXX
invoke ReverseSearch, eip, "e8????????"
invoke PrintNum, reg00, 16

// Reverse search:
//   CALL XXXXXXXX
//   PUSH 0
invoke ReverseSearch, eip, "e8????????6a00"
invoke PrintNum, reg00, 16

4.7.6  GetPrevOpAddr

Prototype:

GetPrevOpAddr address, N

Explanation:

Calculate address of instruction which is N instructions forward
from instruction at specified address.

Parameters:

Return Value:

Succeeds: address of found instruction
Fails: -1

Example:

invoke GetPrevOpAddr, eip, 1
invoke PrintNum, reg00, 16  // Let's see what we got!

4.7.7  GetNextOpAddr

Prototype:

GetNextOpAddr address, N

Explanation:

Calculate address of assembler instruction which is N instructions (maximally 127)
back from instruction at specified address.

Parameters:

Return Value:

Succeeds: address of found instruction
Fails: -1

Example:

invoke GetNextOpAddr, eip, 1
invoke PrintNum, reg00, 16  // Let's see what we got!

4.7.8  GetProcAddress

Prototype:

GetProcAddress funcname, dllname

Explanation:

Return address of funcname in dllname.

Parameters:

Return Value:

Succeeds: function's address
Fails: -1

Example:

invoke GetProcAddress, "MessageBoxA", "user32.dll"
invoke PrintNum, reg00, 16  // Let's see what we got!

4.7.9  Fill

Prototype:

Fill address, len, value

Explanation:

Fill writes len value bytes to starting of address.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// fill 10 bytes "NOP" to address starting from EIP
invoke Fill, eip, 10, 0x90

4.7.10  ReplaceBytes

Prototype:

ReplaceBytes address, find, repl, len

Explanation:

ReplaceBytes "find" starting at address, and replace it with "repl" for len times.

Parameters:

Return Value:

Succeeds: return the "find"'s address.
Fails: -1

Example:

invoke ReplaceBytes, eip, 0x90909090, 0x51515151, 1

4.7.11  ReplaceBytesEx

Prototype:

ReplaceBytesEx address, len, find, repl

Explanation:

Starting from address, replace "find" to "repl", in len bytes.
Supports wildcard "??". One "??" for one byte.
Attention:
1. The length of "find" and "repl" must be the same. For example, if "find" is "60e8??",
   it is 3 bytes, then length of "repl" must also be 3 bytes.
2. The "??" in "find" will not be replaced. For example, if "find" is "60e8??",
   "repl" is "123456", then after replacement, it will be "1234??",
   the original byte of "??" will be kept.

Parameters:

Return Value:

Succeeds: 1, have at least one replacement.
Fails: 0, no replacement.

Example:

invoke ReplaceBytesEx, eip, 10, "60e8??", "909090"

4.7.12  CopyBytesTo

Prototype:

CopyBytesTo addrsrc, addrdest, len

Explanation:

Copy len bytes from addrsrc to addrdest.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke CopyBytesTo, eip, 0x401000, 10

4.8  Assembly API

4.8.1  ASM

Prototype:

ASM address, command

Explanation:

Converts command in ASCII form to binary 32-bit code.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke asm, eip, "mov eax, edx"

4.8.2  __asm

Prototype:

__asm { }

Explanation:

Embedded asm, must invoke like the following type:
__asm
{
mov eax, 1
push 0
call ExitProcess
}

Attention:
1. We can use "//", ";" for line comment, "/* */" for block comment.
2. It is not allowed to use registers of OllyMachine.
3. Embedded asm will be compiled, if the size of the compiled code greater than 2046 bytes,
   then we must separate a big __asm{} block into several smaller block.

For example:

__asm
{
mov eax, 1
// ...
// ...
mov ecx, 1
}

If the assembler prompt that the size of compiled embedded asm is too big,
then we must separate this big block into several smaller blocks:

__asm
{
mov eax, 1
// ...
}
__asm
{
// ...
mov ecx, 1
}

Continue separating... until the assembler does not give you an error prompt any more.
Actually I think 2046 bytes is enough for most of the situations, if not, please let me know.

Parameters:

None

Return Value:

None

Example:

__asm
{
mov eax, 1

push 0
call ExitProcess
}

4.8.3  Analyse

Prototype:

Analyse address

Explanation:

Analyzes executable code of specified module starting at address.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke Analyse, eip

4.9  Running API

4.9.1  RunToReturn

Prototype:

RunToReturn

Explanation:

Executes "Run to return" in OllyDbg

Parameters:

None

Return Value:

None

Example:

RunToReturn

4.9.2  RunToUserCode

Prototype:

RunToUserCode

Explanation:

Executes "Run to user code" in OllyDbg

Parameters:

None

Return Value:

None

Example:

RunToUserCode

4.9.3  Run

Prototype:

Run

Explanation:

Executes F9 in OllyDbg

Parameters:

None

Return Value:

None

Example:

Run

4.9.4  AnimateInto

Prototype:

AnimateInto

Explanation:

Executes "Animate into" in OllyDbg

Parameters:

None

Return Value:

None

Example:

AnimateInto

4.9.5  AnimateOver

Prototype:

AnimateOver

Explanation:

Executes "Animate over" in OllyDbg

Parameters:

None

Return Value:

None

Example:

AnimateOver

4.9.6  StepInto

Prototype:

StepInto

Explanation:

Execute F7 in OllyDbg.

Parameters:

None

Return Value:

Succeeds: 1
Fails: 0

Example:

StepInto

4.9.7  StepIntoS

Prototype:

StepIntoS times

Explanation:

Execute F7 times in OllyDbg.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke StepIntoS, 3

4.9.8  StepOver

Prototype:

StepOver

Explanation:

Execute F8 in OllyDbg.

Parameters:

None

Return Value:

Succeeds: 1
Fails: 0

Example:

StepOver

4.9.9  StepOverS

Prototype:

StepOverS times

Explanation:

Execute F8 times in OllyDbg.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke StepOverS, 3

4.9.10  ESTI

Prototype:

ESTI

Explanation:

Executes SHIFT-F7 in OllyDbg.

Parameters:

None

Return Value:

None

Example:

ESTI

4.9.11  ESTO

Prototype:

ESTO

Explanation:

Executes SHIFT-F9 in OllyDbg.

Parameters:

None

Return Value:

None

Example:

ESTO

4.9.12  GO

Prototype:

GO address

Explanation:

Executes to specified address (like G in SoftIce)

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke go, 0x401005

4.10  Trace API

Tracing API:

4.10.1  TraceInto

Prototype:

TraceInto

Explanation:

Executes "Trace into" in OllyDbg

Parameters:

None

Return Value:

None

Example:

TraceInto

4.10.2  TraceOver

Prototype:

TraceOver

Explanation:

Executes "Trace over" in OllyDbg

Parameters:

None

Return Value:

None

Example:

TraceOver

4.10.3  TraceIntoCond

Prototype:

TraceIntoCond condition

Explanation:

Traces into calls until cond is true

Parameters:

Return Value:

None

Example:

// Will stop when eip > 0x40100A
invoke TraceIntoCond, "eip > 0x40100A"

4.10.4  TraceOverCond

Prototype:

TraceOverCond condition

Explanation:

Traces over calls until cond is true.

Parameters:

Return Value:

None

Example:

// Will stop when eip > 0x40100A
invoke TraceOverCond, "eip > 0x40100A"

4.11  Breakpoint API

4.11.1  BP

Prototype:

BP address

Explanation:

Set unconditional breakpoint at address.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BP, 0x401000
invoke BP, eip

4.11.2  BC

Prototype:

BC address

Explanation:

Clear unconditional breakpoint at addrress.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BC, 0x401000
invoke BC, eip

4.11.3  BPCND

Prototype:

BPCND address, condition

Explanation:

Set breakpoint on address addr with condition cond.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BPCND, eip, "ecx==FFFFFFFF"

4.11.4  BPL

Prototype:

BPL address, expression

Explanation:

Sets logging breakpoint at address addr that logs expression expr.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// logs the value of eax everytime when EIP's address is passed
invoke BPL, eip, "eax"

4.11.5  BPLCND

Prototype:

BPLCND address, expression, condition

Explanation:

Sets logging breakpoint at address addr that logs expression expr if condition cond is true

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

// logs the value of eax everytime when EIP's address is passed and eax > 1
invoke BPLCND, eip, "eax", "eax > 1"

4.11.6  BPRM

Prototype:

BPRM address, size

Explanation:

Set memory breakpoint on read. Size is size of memory in bytes.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BPRM, 0x401000, 0xff

4.11.7  BPWM

Prototype:

BPWM address, size

Explanation:

Set memory breakpoint on write. Size is size of memory in bytes.

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BPWM, 0x401000, 0xff

4.11.8  BPMC

Prototype:

BPMC

Explanation:

Clear memory breakpoint.

Parameters:

None

Return Value:

Succeeds: 1
Fails: 0

Example:

BPMC

4.11.9  BPHWS

Prototype:

BPHWS address, mode

Explanation:

Set hardware breakpoint. Mode can be 1 - "Execute", 2 - "Read", 3 - "Write"

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BPHWS, 0x401000, 1 // mode - "Execute"

4.11.10  BPHWC

Prototype:

BPHWC address

Explanation:

Delete hardware breakpoint at a specified address

Parameters:

Return Value:

Succeeds: 1
Fails: 0

Example:

invoke BPHWC, 0x401000

4.11.11  EOB

Prototype:

EOB label

Explanation:

Transfer execution to some label on next breakpoint.
Format: EOB LabelName

Parameters:

Return Value:

None

Example:

EOB Break       // set up jump label

invoke bp, 0x40100A // set breakpoint at 0x40100A
run             // run! will occur breakpoint at 0x40100A

halt

// ... (some other instructions)

Break:          // jump to this label when occured breakpoint
invoke msg, "Breakpoint occured!"

4.11.12  EOBINT3

Prototype:

EOBINT3 label

Explanation:

Transfer execution to some label on next int3 breakpoint.
Format: EOBINT3 LabelName

Parameters:

Return Value:

None

Example:

EOBINT3 Break   // set up jump label

run             // run!

halt

// ... (some other instructions)

Break:          // jump to this label when occured int3
invoke msg, "Breakpoint occured!"

4.11.13  EOBHW

Prototype:

EOBHW label

Explanation:

Transfer execution to some label on next hardware breakpoint.
Format: EOBHW LabelName

Parameters:

Return Value:

None

Example:

EOBHW Break     // set up jump label

run             // run!

halt

// ... (some other instructions)

Break:          // jump to this label when occured int3
invoke msg, "Breakpoint occured!"

4.11.14  EOBMEM

Prototype:

EOBMEM label

Explanation:

Transfer execution to some label on next memory breakpoint.
Format: EOBMEM LabelName

Parameters:

Return Value:

None

Example:

EOBMEM Break    // set up jump label

run             // run!

halt

// ... (some other instructions)

Break:          // jump to this label when occured int3
invoke msg, "Breakpoint occured!"

4.11.15  EOE

Prototype:

EOE label

Explanation:

Transfer execution to some label on next exception.
Format: EOE LabelName

Parameters:

Return Value:

None

Example:

EOE exception1      // set up jump label

run

halt

exception1:         // if any exceptions occured, jump to here
invoke msg, "Exception occured!"

4.11.16  COB

Prototype:

COB

Explanation:

Makes script continue execution after a breakpoint has occured (removes EOB)

Parameters:

None

Return Value:

None

Example:

EOB Break       // set up jump label

invoke GetNextOpAddr, eip, 1
invoke bp, reg00 // set breakpoint at next instruction
run             // run! will occur breakpoint at once!

invoke msg, "Continue!" // continue execution here because of COB

halt

// ... (some other instructions)

Break:          // jump to this label when occured breakpoint
invoke msg, "Breakpoint occured!"

COB             // removes EOB

4.11.17  COE

Prototype:

COE

Explanation:

Makes script continue execution after an exception has occured (removes EOE)

Parameters:

None

Return Value