datenstrom
datenstrom

Reputation: 118

Windows API, Python3, kernel32.GetModuleHandleA() call fails

I am working through Grey Hat Python by Justin Seitz and I can not get this example code to work. The program attaches to the process; however, when the module func_resolve() is called kernel32.GetModuleHandleA() returns NULL. I am then unable to get the memory address of printf().

This is part of a debugger class:

    def func_resolve(self,dll,function):

    handle  = kernel32.GetModuleHandleA(dll)
    error = kernel32.GetLastError()
    if handle == False:
        print("kernel32.GetModuleHandleA() failed! Error: %d" % error)
    address = kernel32.GetProcAddress(handle, function)
    error = kernel32.GetLastError()
    if address == False:
        print("kernel32.GetProcAddress() failed! Error: %d" % error)
    kernel32.CloseHandle(handle)

    return address

Output of the error message:

kernel32.GetModuleHandleA() failed! Error: 126

The function call from my test harness:

printf_address = debugger.func_resolve("msvcrt.dll", "printf")

The printf loop I attach to for the test:

from ctypes import *
import time
msvcrt  = cdll.msvcrt
counter = 0
while 1:
    msvcrt.printf(b"Loop iteration: ")
    msvcrt.printf("%d" % counter)
    msvcrt.printf("\n")
    time.sleep(2)
    counter += 1

The problem is very similar to the one here but I am using Python3.4 not the books Python2.5, and my environment is windows XP in virtualbox. He was also trying to use 'msvcr100' and solved the problem by switching to 'msvcrt' which is what the book uses and I have been using.

The objective is to get the address of printf() to set a breakpoint there and watch them as the program loops repetitively calling printf().

Edit: Using process explorer I have also just verified that msvcrt.dll is loaded by the process.

Upvotes: 1

Views: 604

Answers (1)

datenstrom
datenstrom

Reputation: 118

The problem was that Python3.4 was passing the strings as Unicode instead of ASCII. The following changes to the function call solved the problem:

dll = "msvcrt.dll".encode('ascii')
function = "printf".encode('ascii')
printf_address = d.func_resolve(dll, function)

I had originally written this in func_resolve():

handle = kernel32.GetModuleHandleW(dll)

And was still having the original problem I posted, not sure why it wasn't handling the Unicode strings correctly.

Upvotes: 2

Related Questions