Textfile for a registry value

c++ / delphi package - dll injection and api hooking
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Textfile for a registry value

Post by c357323 »

Hello all,

I thank madshi for the great work and for sharing it with us.

I will appreciate any advice to me about the following situation:

There is an application(x) that gets a registry value then uses it to decide what to do next. I want to intercept this registry call and write a callback function which retrives that same value from a text file then returns it to the application(x). I would be calling this application(x) directly from my program through CreateProcess() function.

What is the best method to handle this situation.

Thanks in advance

Note: I use Visual C++
-----
c357
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Quite easy: Write a little dll which hooks RegQueryValueExA/W and does the text file stuff instead of reading the registry. Then in your application use madCodeHook's CreateProcessEx(usualCreateProcessParams, 'yourHook.dll') instead of CreateProcess. That's it.
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

Hi madshi,

The CreateProcessEx worked but the hook didn't. I don't know what went wrong.:?

I will post here the .dll and the calling code:

---------------------------------- Start of My.dll ----------------------------------


#include <windows.h>
#include "madCHook.h"

// ***************************************************************

LONG (WINAPI *RegQueryValueExNext) (HKEY hKey, // handle to key
LPCTSTR lpValueName, // value name
LPDWORD lpReserved, // reserved
LPDWORD lpType, // type buffer
LPBYTE lpData, // data buffer
LPDWORD lpcbData // size of data buffer
);

// ***************************************************************

LONG WINAPI RegQueryValueExCallback (HKEY hKey, // handle to key
LPCTSTR lpValueName, // value name
LPDWORD lpReserved, // reserved
LPDWORD lpType, // type buffer
LPBYTE lpData, // data buffer
LPDWORD lpcbData // size of data buffer
)
{
MessageBox(0, lpValueName, "Registry value name", MB_ICONINFORMATION);
RegQueryValueExNext(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
return ERROR_SUCCESS;

}

// ***************************************************************

BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
// InitializeMadCHook is needed only if you're using the static madCHook.lib
InitializeMadCHook();

typedef VOID (*MYPROC)(LPCSTR, LPCSTR, PVOID, PVOID);

HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

// Get a handle to the DLL module.
hinstLib = LoadLibrary("madCHook");

// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "HookAPI");

// If the function address is valid, call the function.

if (fRunTimeLinkSuccess = (ProcAdd != NULL))
(ProcAdd) ("advapi32.dll", "RegQueryValueExA", RegQueryValueExCallback, (PVOID*) &RegQueryValueExNext);

// Free the DLL module.

//fFreeResult = FreeLibrary(hinstLib);
}

// If unable to call the DLL function, display MessageBox.
if (! fRunTimeLinkSuccess)
MessageBox(0, "Unable to load HookAPI of madCHook.dll", "Loading failed...", MB_ICONEXCLAMATION);

}
else if (fdwReason == DLL_PROCESS_DETACH)
// FinalizeMadCHook is needed only if you're using the static madCHook.lib
FinalizeMadCHook();

return true;
}

----------------------------------- End of My.dll ----------------------------------



------------------------------- Start of Calling code ------------------------------

typedef VOID (*MYPROC)(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,
BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION, LPCSTR);

HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

// Get a handle to the DLL module.
hinstLib = LoadLibrary("madCHook");

// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "CreateProcessExA");

// If the function address is valid, call the function.

if (fRunTimeLinkSuccess = (ProcAdd != NULL))
{
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

(ProcAdd) (NULL,
"ApplicationX.exe",
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi,
"My.dll");
}

// Free the DLL module.

//fFreeResult = FreeLibrary(hinstLib);
}

// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
::MessageBox(0, "Unable to load CreateProcessEx of madCHook.dll", "Loading failed...", MB_ICONEXCLAMATION);

--------------------------------- End of Calling code ------------------------------

-----
c357
Last edited by c357323 on Wed Jul 14, 2004 6:17 pm, edited 1 time in total.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Are you sure that the application calls RegQueryValueExA? Maybe it calls RegQueryValueExW? Or RegQueryValueA/W? Or RegQueryMultipleValuesA/W?
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

I have tested it on a program that I coded myself. So I know it uses RegQueryValueExA.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Is the target process stored in a different folder than your hook dll? In that case did you put the madCHook.dll into the system folder? Otherwise the target process will have problems to locate the madCHook.dll.
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

The target application, my.dll and madCHook.dll are all in the same folder.
I also put (as you can see in the code above) Messagebox prompts to inform me of any failed dll or function loading.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Ah, I see. You're loading madCHook.dll, then you're calling HookAPI, then you're unloading madCHook.dll again. When being unloaded madCHook.dll automatically uninstalls all hooks! :idea:
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

Well, I have commented the two calls of FreeLibrary (see the edited code above) and still the same thing:
Working CreateProcessEx, Non-working hook.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

What does "HookAPI" return?

Perhaps you can test the hooking code in your own process first (without any dlls etc involved). That should make debugging easier for you.
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

Calling HookAPI will stop debugging and display the following message:

"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Ah, well, you forgot to specify the calling convention (WINAPI / STDCALL) for the ProcAdd function variable.
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

Where exactly should I specify the calling convention in the code?

I have tried several possible places, every time getting either no change in behaviour or an error in buliding code.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Well, I'm a Delphi programmer, but I think it should look like this:

typedef BOOL (WINAPI *MYPROC)(LPCSTR, LPCSTR, PVOID, PVOID, DWORD);
c357323
Posts: 9
Joined: Tue Jul 13, 2004 4:54 am

Post by c357323 »

What you thought I have already thought about and used, but the error continued.

But you reminded me that I forgot to add the last argument (DWORD) to the function.

And the result is: :crazy: Its WORKING ... !

Thank you very much
Post Reply