Problem:
I am injecting into a program and patching calls but I was wondering if there is any way to walk through the application line by line and find specific calls. _IE: Lets say the program 'Foo.exe' has a call to MessageBox at some location in memory.
If I did the following code: ( just a rough idea )
a = GetModuleHandle ( "<dll>" );
b = GetProcAddress ( a , "<name>" );
swap ( b , (DWORD)*fake_function );
-- Everything works out fine, until you start calling the actual function - which creates a huge loop that goes on forever (ouch).
Now I am not sure about this and I may be wrong but ... does the above code replace the 'Foo.exe' calls in memory, or does it replace the dll's function with 'fake_function'?
I am interested in a few things ...
A ) How can I find all the memory locations in 'Foo,exe' that call MessageBox and replace the memory locations with a call to 'fake_function'?
B ) How does detours solve this problem?
You don't need to locate all the instances where MessageBox gets called, instead you can hook the function. It seems like you have the general idea down, but what you want to do is walk the PE import table for the module in question. When you're walking it, you look for the function you want to hook and then you do the swap. From then on whenever the module calls the MessageBox function it will look for a reference to the function in the import table and find the address to your function where it previously would have found the address to Microsoft's implementation of MessageBox. In your function you can do whatever you want and you can even call the original address of the MessageBox function that you would have had to save upon swap.
Related
I know how I can hook functions from the IAT table, but I have a problem with APIs which were imported by calling LoadLibrary/GetProcAddress functions. I want to know exactly how someone could hook those functions. I realize that I should hook the GetProcAddress function but how can I check the parameters that were passsed to that function?
For example, consider a program which is going to include MessageBoxW via LoadLibrary/GetProcAddress, how can I hook that MessageBoxW and then check the parameters that have been passed to it?
I have searched a lot in StackOverflow and Google, but I couldn't find a step-by-step tutorial about this. So, if you have such a tutorial or article, I would be really grateful to read them.
In order to hook APIs that they are loaded into a binary dynamically with help of LoadLibrary/GetProcAddress, you should intercept return address of the GetProcAddress and name of the functions that passed to it (for example, consider a program try to load MessageBoxA in this way).
In the second step, you should save that original address of MessageBoxA API in a variable like OriginalMessageBoxA.
In the third and final step, you should return address of your modified API (HookedMessageBoxA) to the callee of the GetProcAddress so when the program try to call that address, program redirected to your function. Something like the following one:
VOID* HookedGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
if (std::string(lpProcName).compare("MessageBoxA") == 0)
{
OMessageBoxA = (PMessageBoxA)GetProcAddress(hModule, lpProcName);
return HookedMessageBoxA;
}
else
{
return OGetProcAddress(hModule, lpProcName);
}
}
In that moment, caller will go through your HookedMessageBoxA and you can check parameters that passed to MessageBoxA. As folks said, it is kinda same like normal IAT hook with a minor changes and tricks.
I have a 64bit process, I figured out one of its statically linked library methods.
Source of this method:
int SSL_connect(SSL *s)
{
if (s->handshake_func == 0)
/* Not properly initialized yet */
SSL_set_connect_state(s);
return (s->method->ssl_connect(s));
}
Actual assembly image: click here.
What I want to do is using dll injection in order to access SSL parameter. I'm using x64dbg + ScyllaHide plugin to inject dlls, so any custom injection tools shouldn't be needed. I successfully injected a simple dll into this process, so I think it's enough for this case.
Is there any chance to access the variable from here without any modification of assembly?
Could anyone throw me some bone, please? (I don't ask for code, I just need some hint as I'm rather a newbie to C++ and dll injection world than an expert).
If you can find out the address of the SSL_connect function you can detour it. This means that you can write a JMP instruction at the begin of the method to your patched-method.
If your jumped-to method has the same calling convention and signature you can simply access SSL* and do what you want with it afterwards you can jump back...
To let the jump back work you would need to restore the org code or create a copy of the org method...
Another way would be a Hardware-Break-Point: read for example here.
I have a third-party console application. I need run it from my application but I cannot run it as a separate process (because I need to work with its dependencies: fill Import tables manually, setup hooks etc.). So probably I should call main function of this executable manually. Here is how I'm trying to do this:
Load this EXE using auto hMod = LoadLibrary("console_app.exe")
Fill Import table of this exe manually
Get entry point of this EXE and call it
And I'm stuck with the last step.
Here is how I'm trying to call entry point:
void runMain(HINSTANCE hInst)
{
typedef BOOL(WINAPI *PfnMain)(int, char*[]);
auto imageNtHeaders = ImageNtHeader(hInst);
auto pfnMain = (PfnMain)(DWORD_PTR)(imageNtHeaders->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)hInst);
char* args[] = { R"(<console_app_path>)", R"(arg1)", R"(arg2)" };
pfnMain(3, args);
}
It works. But it works as if there is no arguments.
Where am I wrong? How can I run an executable inside my process with arguments? Thanks.
UPDATE:
I've investigated how my particular third-party exe gets cmd arguments and found that:
It doesn't import GetCommandLine at all and do not call it
After call _initterm call argc and argv arguments are available through cs:argc and cs:argv (see pictures below)
CMD arguments that I pass to my main console app are transferred to
child EXE too.
Can you explain, please, what _initterm actually do and where CMD arguments are actually stored?
You're calling the entry point of the application, not int main(int, char**). Now you may have read that the entry point of a C++ program is int main(int, char**) but that's just a C++ perspective.
The Win32 perspective is different; the entry point is a int (*)(void);. The Visual Studio linker looks for int mainCRTStartup(void); and uses that, unless you specify another entry point with /ENTRY. The default implementation of mainCRTStartup calls GetCommandLine() to fill in argv[] before calling main(argc,argv). There are also other things in mainCRTStartup which you might want to happen: run global ctors, initialize the CRT state, ...
Of course, that's assuming the other program was compiled with Visual C++, but whatever language it's been written in, it must be calling GetCommandLine.
Now, for your problem, here's an interesting observation: GetCommandLine() returns a writeable pointer. You can overwrite the existing command line. Of course, if you control the import tables, you decide what GetCommandLine means. (Remember, as usual there are A and W variants).
One warning: the MSVCRT isn't designed to be initialized twice, neither the static version nor the DLL one. So practically speaking you can't use it, and that will hurt.
[edit]
Your update shows a call to _initterm. That's a MSVCRT function, as I already hinted. Specifically,
/***
*crtexe.c - Initialization for console EXE using CRT DLL
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
...
/*
* routine in DLL to do initialization (in this case, C++ constructors)
*/
extern int __cdecl _initterm_e(_PIFV *, _PIFV *);
extern void __cdecl _initterm(_PVFV *, _PVFV *);
The MSVCRT DLL calls GetCommandLine() on behalf of the EXE.
the entrypoint of executable (EP) have no arguments - so you and can not direct call it with arguments.
usual application got arguments by parsing command line. [w]mainCRTStartup do this - if you have console application linked to c/c++ runtime - this is real EP .
so if you Fill Import table of this exe manually - set exception for GetCommandLineA and GetCommandLineW functions - redirect it to self implementation and return your custom command line.
but if app used not static linked CRT it can import __getmainargs or __wgetmainargs or even _acmdln, or _wcmdln from msvcrt.dll - so already task become complex.
and you assume that relocs exits in EXE, you not handle TLS if it exist, you not handle application manifest, possible dl redirections, etc.
but I cannot run it as a separate process
this is not true. you can and must run it as separate process - this is the best solution.
exec your app by CreateProcess with CREATE_SUSPENDED flag. here you free easy set any CommandLine which you need. you not need manually and not fully correct load EXE but system do this task for you.
after process is created you need inject self DLL to it by using QueueUserAPC (but not CreateRemoteThread !!) and finally call ResumeThread
as result your DLL will be loaded and executed in first EXE thread, just before application EP - and here you can do all needed tasks
I'm trying to create a dll that contains a VCL data module - the idea being that various applications can all load the same dll and use the same database code.
The data module itself is tested ok as part of an application - I've copied the form over to my dll project.
So in the dll entry point method, I need to initialize the data module:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
//if I don't call this, I get an exception on initializing the data module
CoInitialize(NULL);
//initialize a standard VCL form; seems to works fine
//I'm not using Application->CreateForm as I don't want the form to appear straight away
if(!MyForm) MyForm = new TMyForm(Application);
//this doesn't work - the thread seems to hang in the TDataModule base constructor?
//I've also tried Application->CreateForm; same result
if(!MyDataModule) MyDataModule = new TMyDataModule(Application);
}
I've also seen something about how I need to call Application->Initialize before creating the form but this doesn't seem to make any difference.
Any ideas?
Thanks
You really should not be doing very much work in your DllEntryPoint() at all. Certainly not calling CoInitialize(), anyway. It is not the DLL's responsibility to call that when loaded. It is the calling app's responsibility before loading the DLL.
You should either:
export an additional function to initialize your DLL and then have the app it after loading the DLL (same for uninitialing the DLL before unloading it)
don't create your TForm/TDataModule until the first time the DLL actually needs them.
move your TForm/TDataModule into their own worker thread inside the DLL. In this case, you would then call CoIniitalize().
And in all cases, don't relay on the DLL's Application object to manage the lifetime of your TForm/TDataModule. Free them yourself instead before the DLL is unloaded.
I need to automate a specific version of Excel (2003), independent of the default version installed on the target machine. For this purpose, I am using the following steps:
launch Excel by supplying the desired executable to CreateProcess
find the main and accessible window with EnumWindows and EnumChildWindows
use AccessibleObjectFromWindow to get an object from the Excel object model
do the automation stuff through COM smart pointers
This all works fine, but the Excel process will not terminate after a call to Quit on the ExcelApplication object. The same setup with Word works as intended, and the process terminates as it should. Any idea about why Excel behaves differently would be much appreciated.
I've read about similar problems when automating Excel from .NET, where dangling COM references are the reason. However, if that is the reason in my C++ case as well, I don't understand why. Even if I do nothing except Quit, the process still remains alive:
/* create process, get handle to accessible Excel window */
Excel11::_ApplicationPtr excelApplication;
try
{
Excel11::WindowPtr::Interface* pInterface;
if ( ::AccessibleObjectFromWindow( hwndExcelAccessible, OBJID_NATIVEOM, IID_IDispatch, reinterpret_cast< void** >( &pInterface ) ) == S_OK )
{
excelApplication = pInterface->Application;
pInterface->Release();
}
}
catch ( _com_error& e ) { /* omitted */ }
excelApplication->Quit();
What you are doing is no longer supported by Microsoft: http://support.microsoft.com/kb/257757 (it talks about server-side code, but it references any non-interactive solutions regardless of architecture).
That notwithstanding, I believe I ran into a similar problem in some .Net code a while back and the solution was to forcibly kill Excel when done with it. I can't remember the exact reason why that had to be done, though.