Totem
Totem

Reputation: 7349

GetProcAddress return value

I am learning how to create a simple debugger in python, using ctypes on Windows 7. My problem is that the code given below seems to be returning an invalid address(this is my guess as to the problem), but I can't figure out why. I thought perhaps it is because the handle being returned is either no longer valid by the time my code uses it, or maybe I am being returned a handle that has nothing to do with my script due my simply providing "msvcrt.dll" as the module. I've done a lot of tinkering around, but haven't found a solution as yet.

EDIT: The address is returning as False. I am getting the following error from the snippet below:

ERROR 126 : The specified module could not be found.

def func_resolve(self, dll, function):
    error = None

    handle = kernel32.GetModuleHandleA(dll)
    if handle == False:
        print "Handle is FALSE"
        error = GetLastError()

    address = kernel32.GetProcAddress(handle, function)
    if address == False:
        print "Address is FALSE"
        error = GetLastError()

    if error is not None:
        print "ERROR %d : %s" % (error, FormatError(error))
        return False

    kernel32.CloseHandle(handle)

    return address

The above code is called from this short test script:

import my_debugger

debugger = my_debugger.debugger()

pid = raw_input("Input PID of process to attach to: ")
debugger.attach(int(pid))

printf_address = debugger.func_resolve("msvcrt.dll", "printf")
print "[*] Address of printf: 0x%08x" % printf_address
debugger.bp_set(printf_address)

debugger.run()
debugger.detach()

This is the script whose process I am attaching to:

from ctypes import *
import time

msvcrt = cdll.msvcrt
counter = 0

while True:
    msvcrt.printf("Loop iteration %d /n", counter)
    time.sleep(2)
    counter += 1

So I run the above script, find the PID in task manager, then run my test script and give it the PID. I get the following output each time. The user-defined breakpoint at printf is never reached, and it's address is always given as 0x00000000, which doesn't seem right.

Input PID of process to attach to: 8124
Process PID: 8124
[*] Address of printf: 0x00000000       
[*] Setting breakpoint at 0x00000000    
[*] Waiting for debug events...
[*] Event Code: 3       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 6       Thread ID: 7664
[*] Event Code: 2       Thread ID: 7124
[*] Event Code: 1       Thread ID: 7124
[*] Exception address: 0x76e00590
[*] Hit the first breakpoint
[*] Event Code: 4       Thread ID: 7124

Can anyone see what I am doing wrong? I can provide all the code if need be..

Upvotes: 1

Views: 1646

Answers (2)

Mike
Mike

Reputation: 435

I have being putting together a repository in github using the book as a template but changing to support x64 on windows 10 https://github.com/stavinski/grayhat_python_redux/tree/master/chapter03, I came across same issue as mentioned in other comments the wrong DLL is being used, I used the following to fix the issue:

msvcrt = cdll[ctypes.util.find_msvcrt()]

If you make sure this is used whenever you want to resolve msvcrt you should be good to go.

Upvotes: 1

omega
omega

Reputation: 11

I've also been working through the GreyHat Python book, and have stubbornly converted the my_debugger.py file to support 64bit debugging. I have found the solution to this problem.

Setup your func_resolve to something like:

def func_resolve(self,dll,function):

    _GetModuleHandleA = kernel32.GetModuleHandleA
    _GetModuleHandleA.restype = POINTER(c_void_p)

    _GetProcAddress = kernel32.GetProcAddress
    _GetProcAddress.restype = c_void_p

    handle = _GetModuleHandleA(dll)
    if handle is None:
        print 'Error getting handle'

    address = _GetProcAddress(handle, function)
    if address is None:
        print 'Error getting address'

    kernel32.CloseHandle(handle)
    return address

This should return a valid 64bit address for the function.

Upvotes: 1

Related Questions