Jump to content

1 Screenshot

About This File

MemoryUDF - AutoIt Memory Management & Assembly Library

A comprehensive AutoIt User Defined Function (UDF) library for advanced memory manipulation and inline assembly execution. This library provides powerful tools for reading/writing process memory, pointer chain traversal, pattern scanning, and assembly code injection.

Features

Memory Operations

  • Process Memory Access: Read/write memory from external processes
  • Pointer Chain Support: Navigate complex pointer structures with x86/x64 compatibility
  • Module Management: Get base addresses and sizes of loaded modules
  • Memory Protection: Change memory protection flags
  • Memory Utilities: Copy, fill, compare, and dump memory regions

Assembly & Code Injection

  • Inline Assembly: Compile and execute machine code directly
  • Code Injection: Inject assembly code into remote processes
  • Function Hooking: Hook and unhook functions with jump patches
  • Code Cave Creation: Create NOP sleds for code modification
  • Assembly Helpers: Generate common x86 instructions programmatically

Pattern Scanning & Search

  • Pattern Scanning: Search for byte patterns with wildcard support
  • String Search: Find ASCII/Unicode strings in memory (case-sensitive/insensitive)
  • Value Search: Search for integers, floats, and hex sequences
  • AOB Scanning: Array of Bytes scanning with wildcard support
  • Region Scanning: Scan entire module memory regions

Advanced Features

  • Memory Snapshots: Compare memory states to detect changes
  • Array Operations: Read/write arrays of values efficiently
  • String Operations: Handle null-terminated strings (ASCII/Unicode)
  • Memory Freezing: Continuously write values to addresses
  • Page Information: Query memory page properties

Requirements

  • AutoIt Version: 3.3.14+
  • Operating System: Windows (x86/x64)
  • Required DLLs: Kernel32.dll, Psapi.dll, User32.dll
  • Privileges: SeDebugPrivilege recommended for external process access

Installation

  1. Download MemoryUDF.au3
  2. Include in your AutoIt script:
#include "MemoryUDF.au3"

Quick Start

Basic Memory Reading

; Enable debug privilege for external process access
_Memory_SetPrivilege("SeDebugPrivilege", True)

; Open process handle
Local $ahHandle = _Memory_Open("notepad.exe")
If Not @error Then
    ; Read a 4-byte integer from memory
    Local $iValue = _Memory_Read($ahHandle, 0x12345678, "int")
    ConsoleWrite("Value: " & $iValue & @CRLF)
    
    ; Close handle when done
    _Memory_Close($ahHandle)
EndIf

Pointer Chain Navigation

Local $ahHandle = _Memory_Open("game.exe")
If Not @error Then
    ; Get module base address
    Local $iModuleBase = _Memory_GetModuleBaseAddress($ahHandle, "game.dll")
    
    ; Define pointer chain offsets
    Local $aOffsets[3] = [0x28, 0x1D8, 0x6C0]
    
    ; Read value through pointer chain
    Local $iValue = _Memory_ReadPointer($ahHandle, $iModuleBase + 0x123456, $aOffsets, "int")
    ConsoleWrite("Player Health: " & $iValue & @CRLF)
    
    _Memory_Close($ahHandle)
EndIf

Assembly Code Execution

; Execute inline assembly (MOV EAX, 42; RET)
Local $iResult = _ASM_QuickExecute("B82A000000C3")
ConsoleWrite("Assembly result: " & $iResult & @CRLF) ; Output: 42

Pattern Scanning

Local $ahHandle = _Memory_Open("game.exe")
If Not @error Then
    Local $iModuleBase = _Memory_GetModuleBaseAddress($ahHandle, "game.exe")
    
    ; Search for byte pattern with wildcards
    Local $iAddress = _Memory_PatternScan($ahHandle, $iModuleBase, 0x100000, "8B 0D ?? ?? ?? ?? 85 C9")
    
    If Not @error Then
        ConsoleWrite("Pattern found at: 0x" & Hex($iAddress) & @CRLF)
    EndIf
    
    _Memory_Close($ahHandle)
EndIf

Core Functions

Memory Management

  • _Memory_Open($vProcess, $iAccess, $bInherit) - Open process handle
  • _Memory_Close($ahHandle) - Close process handle
  • _Memory_Read($ahHandle, $iAddress, $sType) - Read memory value
  • _Memory_Write($ahHandle, $iAddress, $vData, $sType) - Write memory value
  • _Memory_ReadPointer($ahHandle, $iBaseAddress, $aOffsets, $sType) - Read through pointer chain
  • _Memory_WritePointer($ahHandle, $iBaseAddress, $aOffsets, $vData, $sType) - Write through pointer chain

Module Operations

  • _Memory_GetModuleBaseAddress($ahHandle, $sModule) - Get module base address
  • _Memory_GetProcessBaseAddress($ahHandle) - Get main executable base address
  • _Memory_GetProcessModules($ahHandle) - List all process modules
  • _Memory_GetModuleSize($ahHandle, $sModule) - Get module size

Assembly Functions

  • _ASM_Compile($sHexCode) - Compile hex machine code to executable memory
  • _ASM_Execute($pCode, $iParam1, $iParam2, $iParam3, $iParam4) - Execute compiled code
  • _ASM_Free($pCode) - Free compiled code memory
  • _ASM_QuickExecute($sHexCode) - Compile and execute in one call
  • _ASM_Inject($ahHandle, $sHexCode, $bAutoFree) - Inject code into remote process

Pattern Scanning

  • _Memory_PatternScan($ahHandle, $iStartAddress, $iSize, $sPattern) - Find first pattern match
  • _Memory_PatternScanAll($ahHandle, $iStartAddress, $iSize, $sPattern, $iMaxResults) - Find all matches
  • _Memory_StringSearch($ahHandle, $iStartAddress, $iSize, $sString, $bUnicode, $bCaseSensitive) - Search for strings
  • _Memory_IntegerSearch($ahHandle, $iStartAddress, $iSize, $iValue, $sType) - Search for integer values
  • _Memory_FloatSearch($ahHandle, $iStartAddress, $iSize, $fValue, $bDouble) - Search for float values

Assembly Helpers

  • _ASM_CreateJump($iFrom, $iTo, $bShort) - Generate JMP instruction
  • _ASM_CreateCall($iFrom, $iTo) - Generate CALL instruction
  • _ASM_CreatePush($iValue) - Generate PUSH instruction
  • _ASM_CreateMov($iRegister, $iValue) - Generate MOV instruction
  • _ASM_CreateNOP($iCount) - Generate NOP sled
  • _ASM_CreateRet($iPopBytes) - Generate RET instruction

Function Hooking

  • _ASM_HookFunction($ahHandle, $iTargetAddress, $iHookAddress, $iNOPCount) - Hook function
  • _ASM_UnhookFunction($ahHandle, $iTargetAddress, $sOriginalBytes) - Restore original function

Utility Functions

  • _Memory_Protect($ahHandle, $iAddress, $iSize, $iProtection) - Change memory protection
  • _Memory_ReadString($ahHandle, $iAddress, $iMaxLength, $bUnicode) - Read null-terminated string
  • _Memory_WriteString($ahHandle, $iAddress, $sString, $bUnicode, $bNullTerminate) - Write string
  • _Memory_ReadArray($ahHandle, $iAddress, $iCount, $sType) - Read array of values
  • _Memory_WriteArray($ahHandle, $iAddress, $aArray, $sType) - Write array of values
  • _Memory_Copy($ahHandle, $iSourceAddress, $iDestAddress, $iSize) - Copy memory region
  • _Memory_Fill($ahHandle, $iAddress, $iSize, $iByte) - Fill memory with byte value
  • _Memory_Compare($ahHandle, $iAddress1, $iAddress2, $iSize) - Compare memory regions
  • _Memory_DumpRegion($ahHandle, $iAddress, $iSize) - Dump memory to hex string

Data Types

Supported data types for memory operations:

  • "byte" - 1 byte (0-255)
  • "word", "short" - 2 bytes
  • "int", "dword" - 4 bytes (default)
  • "int64", "uint64" - 8 bytes
  • "float" - 4-byte floating point
  • "double" - 8-byte floating point
  • "ptr" - Pointer size (4 bytes on x86, 8 bytes on x64)

Constants

Process Access Rights

  • $PROCESS_ALL_ACCESS - Full access rights
  • $PROCESS_VM_READ - Read memory access
  • $PROCESS_VM_WRITE - Write memory access
  • $PROCESS_VM_OPERATION - Memory operation access

Memory Protection

  • $PAGE_EXECUTE_READWRITE - Execute, read, and write access
  • $MEM_COMMIT - Commit memory pages
  • $MEM_RESERVE - Reserve memory pages
  • $MEM_RELEASE - Release memory pages

Assembly Registers

  • 8-bit: $AL, $CL, $DL, $BL, $AH, $CH, $DH, $BH
  • 16-bit: $AX, $CX, $DX, $BX, $SP, $BP, $SI, $DI
  • 32-bit: $EAX, $ECX, $EDX, $EBX, $ESP, $EBP, $ESI, $EDI
  • 64-bit: $RAX, $RCX, $RDX, $RBX, $RSP, $RBP, $RSI, $RDI, $R8-$R15

Error Handling

All functions use AutoIt's @error system for error reporting:

  • @error = 0 - Success
  • @error > 0 - Error occurred (check function documentation for specific error codes)

Always check @error after function calls:

Local $iValue = _Memory_Read($ahHandle, $iAddress, "int")
If @error Then
    ConsoleWrite("Error reading memory: " & @error & @CRLF)
Else
    ConsoleWrite("Value: " & $iValue & @CRLF)
EndIf

Best Practices

  1. Enable Debug Privilege: Call _Memory_SetPrivilege("SeDebugPrivilege", True) before accessing external processes
  2. Handle Cleanup: Always call _Memory_Close() to free resources
  3. Check Errors: Verify @error after each function call
  4. Use Appropriate Types: Choose the correct data type for your memory operations
  5. Validate Addresses: Ensure memory addresses are valid before access
  6. Test Patterns: Verify pattern strings are correctly formatted with spaces

Security Considerations

  • This library requires elevated privileges for external process access
  • Memory manipulation can cause application crashes or system instability
  • Always validate input parameters and memory addresses
  • Use appropriate error handling to prevent unexpected behavior
  • Be cautious when injecting code into critical system processes

Compatibility

  • Architecture: Supports both x86 and x64 processes
  • AutoIt: Compatible with AutoIt 3.3.14 and later versions
  • Windows: Works on Windows Vista and later versions
  • Processes: Can access both 32-bit and 64-bit processes (with appropriate AutoIt version)

Author

Dao Van Trong - TRONG.PRO

License

This UDF is provided as-is for educational and development purposes. Use responsibly and in accordance with applicable laws and regulations.

Edited by Trong
Update document!


User Feedback

Recommended Comments

OhItsThatGuy

Posted

Hi Trong, I love your work! Clean code, easy to read and use. I checked out your other projects as well!

Regarding your ImageSearch library, can I make a small request?

Having a scan function that can take a bitmap handle would be amazing. This would allow a finer control by eliminating the need to force a re-scan on each iteration of _ImageSearch(..)

_ImageSearch_ScanSnapshot($hImage = -1, $sImageFile, $iLeft = 0, $iTop = 0, $iRight = @DesktopWidth, $iBottom = @DesktopHeight, $iTolerance = 10, $iTransparent = -1, $iMultiResults = 1, $iCenterPos = 1, $iReturnDebug = 1, $fMinScale = 1.0, $fMaxScale = 1.0, $fScaleStep = 0.1, $iFindAllOccurrences = 0)

 

I realize we can use a delimiter | to search for multiple images but there are situations where a user would want to break images into categories and run different tolerance for each set, as well as focus on a particular area of the screen for each set.

We can take a snap shot using GDI+ through AutoIt as such:

Func _Img_TakeSnapshot($_iCanvasLeft=0,$_iCanvasTop=0,$_iCanvasWidth=@DesktopWidth,$_iCanvasHeight=@DesktopHeight)

    ; Clean up resources
    _GDIPlus_BitmapDispose($g_myImg_hImage)
    _WinAPI_DeleteObject($g_myImg_hMatWinCapture)

    ; Screen grab an area (should ideally be full screen)
    ; Use _Img_ScanSnapshotArea to scan

    ; Capture entire desktop or selected area
    $g_myImg_hMatWinCapture = _ScreenCapture_Capture("", $_iCanvasLeft, $_iCanvasTop, $_iCanvasWidth, $_iCanvasHeight, False)

    ; Create a Bitmap object from a bitmap handle (Using previously taken SnapShot)
    $g_myImg_hImage = _GDIPlus_BitmapCreateFromHBITMAP($g_myImg_hMatWinCapture)

    ; Save last scanned box dimensions
    $g_myImg_aAreaLastScan[0] = $_iCanvasLeft                           ; X Left Upper
    $g_myImg_aAreaLastScan[1] = $_iCanvasTop                            ; Y Left Upper
    $g_myImg_aAreaLastScan[2] = $_iCanvasLeft + $_iCanvasWidth          ; X Right Lower
    $g_myImg_aAreaLastScan[3] = $_iCanvasTop + $_iCanvasHeight          ; Y Right Lower
    $g_myImg_aAreaLastScan[4] = $_iCanvasWidth                          ; Box Width
    $g_myImg_aAreaLastScan[5] = $_iCanvasHeight                         ; Box Height

    ; Debug
    ;If $g_myImg_bDebugConsole = True Then ConsoleWrite("+ Snapshot:: (" & $_iCanvasLeft & ", " & $_iCanvasTop & ", " & $_iCanvasWidth & ", " & $_iCanvasHeight & ")" & @CRLF)

EndFunc

Or perhaps that can be handled by the dll. Those are just my thoughts, I'm not an expert a this.

Thank you for putting together this amazing UDF!

tubaba

Posted

First of all, thank you for providing a great user experience. However, I do have an issue to bring up. It seems that your DLL automatically corrects parts that exceed the screen, confining them within the frame of 0,0,@DesktopWidth,@DesktopHeight. But there are many application scenarios with multiple screens, which means that screen coordinates should not be limited to the range of the first screen. In earlier versions, I found that the coordinate correction was done in the UDF.

1.thumb.png.e0948e0023942a08c11910f8814928f1.png

tubaba

Posted

 

Get information of all screens

Global $__MonitorList[1][5], $__MonitorListBase[1][5]
$__MonitorListBase[0][0] = 0



_GetMonitors()



Func  _GetMonitors()
    $__MonitorList = $__MonitorListBase
    Local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam")
    DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0)
    DllCallbackFree($handle)
EndFunc   ;==>_GetMonitors

Func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam)
    Local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect)
    $__MonitorList[0][0] += 1
    ReDim $__MonitorList[$__MonitorList[0][0] + 1][5]
    $__MonitorList[$__MonitorList[0][0]][0] = $hMonitor
    $__MonitorList[$__MonitorList[0][0]][1] = DllStructGetData($Rect, "left")
    $__MonitorList[$__MonitorList[0][0]][2] = DllStructGetData($Rect, "top")
    $__MonitorList[$__MonitorList[0][0]][3] = DllStructGetData($Rect, "right")
    $__MonitorList[$__MonitorList[0][0]][4] = DllStructGetData($Rect, "bottom")
    Return 1 ; Return 1 to continue enumeration
EndFunc   ;==>_MonitorEnumProc

 

tubaba

Posted

Scene Setup:
The user has two monitors. The primary monitor has a resolution of 1920×1080, corresponding to coordinates Left: 0, Top: 0, Right: 1920, Bottom: 1080.
The secondary monitor has a resolution of 1600×900, corresponding to coordinates Left: –1600, Top: 0, Right: 0, Bottom: 900.
The same image is searched sequentially across both monitors.


Test 1 – Target image present on both monitors: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {1}[274|195|28|30](time=109ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[-1488|130|28|30](time=125ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 2 match(es)!
Match #1 found at: 274, 195
Match #2 found at: -1488, 130


Test 2 – Target image absent on primary monitor but present on secondary: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {0}[](time=172ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[-1488|130|28|30](time=156ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 1 match(es)!
Match #1 found at: -1488, 130


Test 3 – Target image present on primary monitor but absent on secondary: result returned incorrectly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {1}[274|195|28|30](time=94ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[274|195|28|30](time=156ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 2 match(es)!
Match #1 found at: 274, 195
Match #2 found at: 274, 195

2025-10-31_112041.thumb.png.d7f20d457630c98ea255e59f881f3ee7.png

out of range

 


Test 4 – Target image absent on both monitors: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {0}[](time=141ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {0}[](time=203ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.

×
×
  • Create New...