1 (изменено: ypppu, 2014-06-11 20:41:02)

Тема: AHK: Узнать адрес памяти Dll файла

Помогите пожалуйста. Программа в свой процесс загружает свои Dll. Как можно узнать адрес в памяти программы Dll файла?

То есть например типо такого:


processName := igra.exe
adres1 := kakoito.dll
adres2 := 0x123
adres3 := adres1 + adres2
ProcessReadMemory(adres3, processName)

Для чтения и записи в память я использую это:

ProcessReadMemory(address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)
    VarSetCapacity(numBytesRead, A_PtrSize, 0)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 24, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "PtrP", numBytesRead, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to read process memory.`n`nError code:`t" . A_LastError)

    if !numBytesRead
        throw Exception("Read 0 bytes from the`n`nprocess:`t" . processIDorName . "`naddress:`t" . address)

    return NumGet(buf, 0, type)
}

ProcessWriteMemory(data, address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)
    NumPut(data, buf, 0, type)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 40, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("WriteProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "UInt", 0, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to write process memory.`n`nError code:`t" . A_LastError)

    return result
}

2 (изменено: YMP, 2013-10-06 16:58:23)

Re: AHK: Узнать адрес памяти Dll файла

Попробуйте так. Чтобы работало с 32- и 64-битными процессами, запускать скрипт в АНК x64.


Process = program.exe
DllName = kernel32.dll

SetFormat, Integer, Hex
Addr := GetDllAddr(DllName, Process)

If (Addr != 0) {
    MsgBox, %Addr%
}
Else {
    MsgBox, Ошибка
}

GetDllAddr(DllName, ProcessName)
{
    static StructSize, AddrOffset, NameOffset
    If (A_PtrSize = 4) {
        StructSize := 1064
        AddrOffset := 20
        NameOffset := 32
    }
    Else {
        StructSize := 1080
        AddrOffset := 24
        NameOffset := 48
    }
    static FLAGS := 0x18        ; TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32
    static INVALID_HANDLE_VALUE := -1
    static MODULEENTRY32
    VarSetCapacity(MODULEENTRY32, StructSize, 0)
    NumPut(StructSize, MODULEENTRY32, 0, "uint")

    Process, Exist, %ProcessName%
    If (ErrorLevel = 0)
        Return 0

    snapMod := DllCall("CreateToolhelp32Snapshot", "uint", FLAGS
                                                 , "uint", ErrorLevel
                                                 , "ptr")
    If (snapMod = INVALID_HANDLE_VALUE) {
        Return 0
    }

    If DllCall("Module32FirstW", "ptr", snapMod, "ptr", &MODULEENTRY32)
    {
        pszModule := &MODULEENTRY32 + NameOffset
        If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
        {
            DllCall("CloseHandle", "ptr", snapMod)
            Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
        }

        While DllCall("Module32NextW", "ptr", snapMod, "ptr", &MODULEENTRY32)
        {
            If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
            {
                DllCall("CloseHandle", "ptr", snapMod)
                Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
            }
        }
    }
    DllCall("CloseHandle", "ptr", snapMod)
    Return 0
}

3

Re: AHK: Узнать адрес памяти Dll файла

Спасибо, работает.

4

Re: AHK: Узнать адрес памяти Dll файла

Внёс небольшие исправления: размер структуры нужно писать в неё как "uint". Также указал тип возвращаемого значения для CreateToolhelp32Snapshot как "ptr", поскольку справка наводит на подозрения, что даже под x64 тип по умолчанию 32-битный.