1
votes

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.

1
Why would you compare a module handle to False? A module handle is a pointer. Why are you calling GetLastError before checking for failure? Did you read the documentation of these functions? Are you setting restype for the functions that you call?David Heffernan
Because I knew it was returning 0x00000000. The error code has moved around a lot over the last 24 hours I have been looking at this, but it is just a toy program I am trying to learn from and I don't care about its efficiency. I have read the documentation, but I also haven't used windows since windows 95 so I am only familiar with UNIX environments. The book hasn't mentioned setting restype at all.datenstrom
OK, well if you're happy with all that, fineDavid Heffernan

1 Answers

2
votes

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.