0

I'm trying to get a handle to a function within a .dll. I am creating a CreateToolHelp32Snapshot and then enumerating over the modules until I find the one I want, from that .dll I want to find a particular function. How do I call GetProcAddress() correctly so that I get the function within 'that' .dll rather than another instance that may be running?

The continuation from the above question would then be, ok so I have a handle to the function, how do I actually call it?

EDIT: As has already been pointed out. I am already in the 3rd party app address space. If getprocaddress will not work, how do I get the entry point for the function using readprocessmemory and necessary offset?

Thanks.

HANDLE h_th_32snap =  CreateToolhelp32Snapshot(0x8u, pid);
if( h_th_32snap == INVALID_HANDLE_VALUE )
  {
    printError( TEXT("CreateToolhelp32Snapshot (of modules)") );
    return( FALSE );
  }

  // Set the size of the structure before using it.
  me32.dwSize = sizeof( MODULEENTRY32 );

  // Retrieve information about the first module,
  // and exit if unsuccessful
  if( !Module32First( h_th_32snap, &me32 ) )
  {
    printError( TEXT("Module32First") );  // show cause of failure
    CloseHandle( h_th_32snap );           // clean the snapshot object
    return( FALSE );
  }

  // Now walk the module list of the process,
  // and display information about each module

  BYTE *d_pointer_qtgui4_dll = 0x0;
  do
  {
    _tprintf( TEXT("\n\n     MODULE NAME:     %s"),   me32.szModule );
    _tprintf( TEXT("\n     Executable     = %s"),     me32.szExePath );
    _tprintf( TEXT("\n     Process ID     = 0x%08X"),         me32.th32ProcessID );
    _tprintf( TEXT("\n     Ref count (g)  = 0x%04X"),     me32.GlblcntUsage );
    _tprintf( TEXT("\n     Ref count (p)  = 0x%04X"),     me32.ProccntUsage );
    _tprintf( TEXT("\n     Base address   = 0x%08X"), (DWORD) me32.modBaseAddr );
    _tprintf( TEXT("\n     Base size      = %d"),             me32.modBaseSize );

    if(!wcsncmp(me32.szModule, L"QtGui4.dll", 255))
    {

              FARPROC test = GetProcAddress(GetModuleHandle( L"QtGui4.dll"),"?rowsInserted@QListView@@MAEXABVQModelIndex@@HH@Z");

    }

  } while( Module32Next( h_th_32snap, &me32 ) );

  CloseHandle( h_th_32snap );

Greg, I would be interested to know why this is wrong? It doesn't throw any errors but it doesn't work either!

function prototype:

QWidget * QWidget::find ( WId id )   [static];

My attempt to call it:

hDLL = GetModuleHandle( L"QtGui4.dll");
if (hDLL != NULL)
{

   func pointer_find = (func)GetProcAddress(hDLL,"?find@QWidget@@SAPAV1@PAUHWND__@@@Z");

   if (!pointer_find)
   {
      // handle the error
      FreeLibrary(hDLL);       
      //return SOME_ERROR_CODE;
   }
   else
   {
      // call the function
       widget = pointer_find(my_hwnd);
   }
}
flavour404
  • 6,184
  • 30
  • 105
  • 136

2 Answers2

1

Not possible, GetProcAddress() requires a module handle. A HMODULE is only valid inside the process in which it was obtained. You would have to do the same kind of thing that GetProcAddress() does, iterating the IAT to find the entrypoint. And apply the base address offset. This is beyond painful to do for another process since you cannot directly access the memory to read the IAT. ReadProcessMemory is required.

Injecting code in the target process is the only reasonable approach. Which is also required to do what I presume you'd want to do next, call the function. Code injection techniques are covered well at codeproject.com

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I am already in the process address space (this is all inside an injected dll), and I am quite familiar with readprocessmemory, what I haven't done before is what I asked basically, how to get an entry point for the function. So using readprocessmemory, how do I find and call the function? – flavour404 Jan 06 '11 at 20:07
  • That's not what your code says. Use 0 for the 2nd argument of CreateToolHelp32Snapshot(). If you're already inside the process then why not just call LoadLibrary + GetProcAddress? ReadProcessMemory is completely unnecessary. – Hans Passant Jan 06 '11 at 20:10
0

If you are in process you are almost there.

GetModuleHandle will get a currently loaded module handle, compared to LoadLibrary which will load a module (and increase the ref count). Just need the right prototype for the function.

typedef void __thiscall (QListView::*rowsInserted)(class QModelIndex const &,int,int);

rowsInserted test = (rowsInserted)GetProcAddress(GetModuleHandle( L"QtGui4.dll"),"?rowsInserted@QListView@@MAEXABVQModelIndex@@HH@Z");

//QListView *object
if( test && object )
  (object.*test)(my_QModelIndex, int_x, int_y);
Greg Domjan
  • 13,943
  • 6
  • 43
  • 59
  • Greg the correct prototype is "protected: virtual void __thiscall QListView::rowsInserted(class QModelIndex const &,int,int)" - so do I just need to go (test(my_QModelIndex, int_x, int_y) and will that do it? – flavour404 Jan 06 '11 at 21:01
  • well you probably shouldn't be calling protected functions unless you where inheriting from this as base at which point I wonder how you got to this function loading... but I'll update the example as best I can – Greg Domjan Jan 06 '11 at 21:11
  • Greg thanks. From everything I have read the QWidget::find(hwnd) function but I think I have my project configured incorrectly so that I am ending up with two instances running. I am resorting to see if the above works and get's me what I want, I just need to get the mangled name for the find function and then I will test it. This whole Qt thing is really confusing, I only want to catch a Qt widget (window) and access a couple of methods. – flavour404 Jan 06 '11 at 21:53
  • Greg I extended my question trying to call a simpler function QWidget::find which only requires one para (a hwnd) but again I am doing something wrong... Interested to know why my signature is wrong. thanks – flavour404 Jan 10 '11 at 00:06