I have a proxy dxgi.dll and I'm trying to detour the Present function in the original dxgi.dll in order to render things on screen. The .dll is successfully loaded and the detour is placed. However the detour crashes the program as soon as my new Present is called. Keep in mind the .dlls and programs are 64-bit.
Below is an image of how the function looks in memory before modification (Start highlighted):
Okay so I just found out I'm not allowed to post images directly on here unless I have 10 reputation, so use this link (replace DOT):
https://imgur DOT com/a/Jf53dYc
I am not sure exactly where it crashes, I believe the program keeps running for a little while, but it definetly crashes in the middle/soon after the detour Present is called, I know this because I can write the pointer to the SwapChain parameter to a file from inside the Present detour before it crashes.
I found the original Present function address using IDA. You can see what IDA says about the function on the picture in the imgur gallery.
I've been looking at the memory and been trying to figure out what is wrong, when I follow the jumps using Cheat engine they lead to the correct places, nevertheless something in the detour is making the program crash. The overriden opcodes also seem to be replaced properly.
I've tried to change the calling convention and return type on my Present function, I read in a dxgi hooking guide that the return type was a HRESULT, I tried changing to this to no avail. As for the calling convention I've tried WINAPI.
I've also looked a little bit into if the stack or registers are being corrupted by my function detour. However I'm not very good with assembly and I can't say for sure if this is the case.
I have a class named Core that takes care of the hooking, here is the header file with some relevant definitions:
#pragma once
#include <iostream>
#include <Windows.h>
#include <intrin.h>
#include <dxgi.h>
#include <fstream>
// Seems my C++ doesn't have QWORD predefined, defining it myself
typedef unsigned __int64 QWORD;
// Definition of the structure of the DXGI present function
typedef __int64 (__fastcall* PresentFunction)(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags);
class Core
{
private:
QWORD originalDllBaseAddress;
QWORD originalPresentFunctionOffset;
public:
void Init();
bool Hook(PresentFunction originalFunction, void* newFunction, int bytes);
~Core();
};
Init starts the process by getting the relevant addresses:
void Core::Init()
{
originalDllBaseAddress = (QWORD)GetModuleHandleA("dxgi_.dll");
originalPresentFunctionOffset = 0x5070;
originalPresentFunction = (PresentFunction)(originalDllBaseAddress + (QWORD)originalPresentFunctionOffset);
Hook(originalPresentFunction, FixAndReturn, 14);
}
Hook tries to place a jump in the target address, I strongly believe the issue is somewhere in here, (comments have now changed my mind, it probably has something to do with assembly, registers or the stack) more specifically the assignments to originalFunction:
bool Core::Hook(PresentFunction originalFunction, void* newFunction, int length)
{
DWORD oldProtection;
VirtualProtect(originalFunction, length, PAGE_EXECUTE_READWRITE, &oldProtection);
memset(originalFunction, 0x90, length);
// Bytes are flipped (because of endianness), could alternatively use _byteswap_uint64()
*(QWORD*)originalFunction = 0x0000000025FF;
// The kind of jump I'm doing here seems to only use 6 bytes,
// and then grabs the subsequent memory address,
// I'm not quite sure if I'm doing this right
*(QWORD*)((QWORD)originalFunction + 6) = (QWORD)newFunction;
DWORD temp;
VirtualProtect(originalFunction, length, oldProtection, &temp);
originalPresentFunction = (PresentFunction)((QWORD)originalFunction + length);
presentAddr = (QWORD)Present;
jmpBackAddr = (QWORD)originalPresentFunction;
return true;
}
I've tried many things when it comes to writing the bytes into memory, but none of them have fixed my problem.
The assignment to "originalPresentFunction" at the end of the function is the address that the detour will attempt to jump back to.
Here is the definition of the detour function, located in Core.cpp:
__int64 __fastcall Present(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags)
{
//The program crashes with and without these file writes.
std::ofstream file;
file.open("HELLO FROM PRESENT.txt");
file << pSwapChain;
file.close();
return originalPresentFunction(pSwapChain, SyncInterval, Flags);
}
This is the function, when called, that causes a crash. As you can see, I am writing the pSwapChain parameter to a file here. I did this to test if the parameters are being passed from the original function. This write is successful, and the contents of the file look like a valid pointer. thus the crash happens after this write. FixAndReturn() is an assembly function.
includelib legacy_stdio_definitions.lib
.data
extern presentAddr : qword
extern jmpBackAddr : qword
; This performs instructions originally performed by dxgi.dll in the
; memory that we've replaced, and then returns
.code
FixAndReturn PROC
call [presentAddr]
mov [rsp+10h],rbx
mov [rsp+20h],rsi
push rbp
push rdi
push r14
jmp qword ptr [jmpBackAddr]
FixAndReturn ENDP
end
I have uploaded the entire code on Github if more code is needed:
https://github.com/techiew/KenshiDXHook
It's been a while, I've been busy with other things but I've now made the detour function work successfully.
After looking at resources on the web and doing a lot of thinking. The answer is quite simple. In my FixAndReturn assembly code, all I need to do is jmp to the detour function, no call is needed. A call might unneccesarily change things we don't want to, and our detour function is already identical to the original function in terms of parameters and whatnot, so it will already read the parameters from the same place that the original function call placed them. This means a jmp will work just fine for running our detour function. No extra pushes or pops are needed in assembly for this to work.
Here is a basic overview of the process:
Our hook is placed by placing a jmp to the beginning of our assembly code.
Our assembly code immediately jumps to our detour/hooked function.
When the detour function is finished, it returns a function call.
This function call uses a typedef which is identical to the original function we hooked. It looks like this:
typedef HRESULT (__fastcall* PresentFunction)(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags);
Returning the function using the typedef is done like this, with the original argument values:
return ((PresentFunction)coreRef->newPresentReturn)(swapChain, syncInterval, flags);
Basically what's happening here is that the address following right after our second assembly code jmp instruction pointing to our detour function is being returned to and called as a function, thus we are jumping to the detour, jumping back, and executing the original code. (coreRef->newPresentReturn contains the address right after the jmp instruction).
We are now adhering to the calling convention of the original Present function, and the parameters we pass in are put in the right places, the registers and stack and whatever are not corrupted in any way.
Resource used: Guidedhacking.com - D3D11 barebones hook
Full code is on my Github: https://github.com/techiew/KenshiHook
Related
I am converting a huge Windows dll to work on both Windows and Linux. The dll has a lot of assembly (and SS2 instructions) for video manipulation.
The code now compiles fine on both Windows and Linux using Intel compiler included in Intel ComposerXE-2011 on Windows and Intel ComposerXE-2013 SP1 on Linux.
The execution, however, crashes in Linux when trying to call a function pointer. I traced the code in gdb and indeed the function pointer doesn't point to the required function (whereas in Windows in does). Almost everything else works fine.
This is the sequence of code:
...
mov rdi, this
lea rdx, [rdi].m_sSomeStruct
...
lea rax, FUNCTION_NAME # if replaced by 'mov', works in Linux but crashes in Windows
mov [rdx].m_pfnFunction, rax
...
call [rdx].m_pfnFunction # crash in Linux
where:
1) 'this' has a struct member m_sSomeStruct.
2) m_sSomeStruct has a member m_pfnFunction, which is a pointer to a function.
3) FUNCTION_NAME is a free function in the same compilation unit.
4) All those pure assembly functions are declared as naked.
5) 64-bit environment.
What is confusing me the most is that if I replace the 'lea' instruction that is supposed to load the function's address into rax with a 'mov' instruction, it works fine on Linux but crashes on Windows. I traced the code in both Visual Studio and gdb and apparently in Windows 'lea' gives the correct function address, whereas in Linux 'mov' does.
I tried looking into the Intel assembly reference but didn't find much to help me there (unless I wasn't looking in the right place).
Any help is appreciated. Thanks!
Edit More details:
1) I tried using square brackets
lea rax, [FUNCTION_NAME]
but that didn't change the behaviour in Windows nor in Linux.
2) I looked at the disassembler in gdb and Windows, seem to both give the same instructions that I actually wrote. What's even worse is that I tried putting both lea/mov one after the other, and when I look at them in disassembly in gdb, the address printed after the instruction after a # sign (which I'm assuming is the address that's going to be stored in the register) is actually the same, and is NOT the correct address of the function.
It looked like this in gdb disassembler
lea 0xOffset1(%rip), %rax # 0xSomeAddress
mov 0xOffset2(%rip), %rax # 0xSomeAddress
where both (SomeAddress) were identical and both offsets were off by the same amount of difference between lea and mov instructions,
But somehow, the when I check the contents of the registers after each execution, mov seem to put in the correct value!!!!
3) The member variable m_pfnFunction is of type LOAD_FUNCTION which is defined as
typedef void (*LOAD_FUNCTION)(const void*, void*);
4) The function FUNCTION_NAME is declared in the .h (within a namespace) as
void FUNCTION_NAME(const void* , void*);
and implemented in .cpp as
__declspec(naked) void namespace_name::FUNCTION_NAME(const void* , void*)
{
...
}
5) I tried turning off optimizations by adding
#pragma optimize("", off)
but I still have the same issue
Off hand, I suspect that the way linking to DLLs works in the latter case is that FUNCTION_NAME is a memory location that actually will be set to the loaded address of the function. That is, it's a reference (or pointer) to the function, not the entry point.
I'm familiar with Win (not the other), and I've seen how calling a function might either
(1) generate a CALL to that address, which is filled in at link time. Normal enough for functions in the same module, but if it's discovered at link time that it's in a different DLL, then the Import Library is a stub that the linker treats the same as any normal function, but is nothing more than JMP [????]. The table of addresses to imported functions is arranged to have bytes that code a JMP instruction just before the field that will hold the address. The table is populated at DLL Load time.
(2) If the compiler knows that the function will be in a different DLL, it can generate more efficient code: It codes an indirect CALL to the address located in the import table. The stub function shown in (1) has a symbol name associated with it, and the actual field containing the address has a symbol name too. They both are named for the function, but with different "decorations". In general, a program might contain fixup references to both.
So, I conjecture that the symbol name you used matches the stub function on one compiler, and (that it works in a similar way) matches the pointer on the other platform. Maybe the assembler assigns the unmangled name to one or the other depending on whether it is declared as imported, and the options are different on the two toolchains.
Hope that helps. I suppose you could look at run-time in a debugger and see if the above helps you interpret the address and the stuff around it.
After reading the difference between mov and lea here What's the purpose of the LEA instruction? it looks to me like on Linux there is one additional level of indirection added into the function pointer. The mov instruction causes that extra level of indirection to be passed through, while on Windows without that extra indirection you would use lea.
Are you by any chance compiling with PIC on Linux? I could see that adding the extra indirection layer.
I want to ask order of function signature, call and definition
like, which one would the computer look first, second and third
So:
#include <iostream>
using namespace std;
void max(void);
void min(void);
int main() {
max();
min();
return;
}
void max() {
return;
}
void min() {
return;
}
So this is what I think,
the computer will go to main and look at the function call, then it will look at the
function signature, and at the last, it will look at the definition.
It is right?
Thank
It is right?
No.
You need to understand the difference between function declarations and function definitions, the difference between compilation, linking, and execution, and the difference between non-virtual and virtual functions.
Function declarations
This is a function declaration: void max(void);. It doesn't tell the compiler anything about what the function does. What it does is to tell the compiler how to call the function and how to interpret the result. When the compiler is compiling the body of some function, call it function A, the compiler doesn't need to know what other functions do. All it needs to know is what to do with the functions that function A calls. The compiler might generate code in assembly or some intermediate language that corresponds to your C++ function calls. Or it might reject your C++ code because your code doesn't make sense.
Determining whether your code makes sense is another key purpose of those function declarations. This is particularly important in C++ where multiple functions can have the same name. How would the compiler know which of the half dozen or so max functions to call if it didn't know about those functions? When your C++ code calls some function, the compiler must find one best match (possibly involving type conversions) with one of those function declarations. Your code doesn't make sense if the compiler can't find a match at all, or if it finds more than one match but can't distinguish one as the best match.
When the compiler does find a best match, the generated code will be in the form of a call to an undefined external reference to that function. Where that function lives is not the job of the compiler.
Function definitions
That void max(void) was a function declaration. The corresponding void max() {...} is the definition of that function. When the compiler is processing void max() {...} it doesn't have to worry about what other functions have called it. It just has to worry about processing void max() {...} . The body of this function becomes assembly or intermediate language code that is inserted into some compiled object file. The compiler marks the address of the entry point to this generated code is marked as such.
Compilation versus linking
So far I've talked about what the compiler does. It generates chunks of low-level code that correspond to your C++ code. That generated code is not ready for prime time because of those external references. Resolving those undefined external references is the job of the linker. The linker is what builds your executable from multiple object files, multiple libraries. It keeps track of where it has put those chunks of code in the executable. What about those undefined external references? If the linker has already placed that reference in the executable, the linker simply fills in the placeholder for that reference. If the linker hasn't come across the definition for that reference, it puts the reference and the placeholder onto a list of still-unresolved references. Every time the linker adds a chunk of code to the executable, it checks that list to see if it can fix any of those still-unresolved references. At the end, you will either have all references resolved or you will still have some outstanding ones. The latter is an error. The former means that you have an executable.
Execution
When your code runs, those function calls are really just some stack management wrapped around the machine language equivalent of that evil goto statement. There's no examining your function declarations; those don't even exist by the time the code is executed. Return? That's a goto also.
Non-virtual versus virtual functions
What I said above pertains to non-virtual functions. Run-time dispatching does occur for virtual functions. That run-time dispatching has nothing to do with examining function declarations. Those virtual functions are perhaps an issue for a different question.
One last thing:
Get out of the habit of using namespace std; Think of it as akin to smoking. It's a bad habit.
As you may know, the compiler converts the program into machine code (via several intermediate steps). Here is the dissassembly of the machine code for main() when compiled on Visual Studio 2012 in debug mode on Windows 8:
int main() {
00C24400 push ebp # Setup stack frame
00C24401 mov ebp,esp
00C24403 sub esp,0C0h
00C24409 push ebx
00C2440A push esi
00C2440B push edi
00C2440C lea edi,[ebp-0C0h] # Fill with guard bytes
00C24412 mov ecx,30h
00C24417 mov eax,0CCCCCCCCh
00C2441C rep stos dword ptr es:[edi]
max();
00C2441E call max (0C21302h) # Call max
min();
00C24423 call min (0C2126Ch) # Call min
return 0;
00C24428 xor eax,eax
}
00C2442A pop edi # Restore stack frame
00C2442B pop esi
00C2442C pop ebx
00C2442D add esp,0C0h
00C24433 cmp ebp,esp
}
00C24435 call __RTC_CheckEsp (0C212D5h) # Check for memory corruption
00C2443A mov esp,ebp
00C2443C pop ebp
00C2443D ret
The exact details will vary from compiler to compiler and operating system to operating system. If min() or max() had arguments or return values, they would be passed as appropriate for the architecture. The key point is that the compiler has already worked out what the arguments and return values are and created machine code that just passes or accepts them.
You can learn more details if you wish to help with debugging or to do low level calls but be aware that the machine code emitted can be highly variable. For example, here is the same code compiled on the same system in release mode (i.e. with optimizations on):
return 0;
01151270 xor eax,eax
}
01151272 ret
As you can see, it has detected that min() and max() do nothing and removed them completely. Since there is now no stack frame to setup and restore, that is gone, leaving a single instruction to set eax to 0 then returning (since the return value is in the eax register).
I have a dll and i wish to create a detour to one of its exported functions,
The dll is not part of windows.
I need to be able to call the real function after my detour (call the real function from a detoured one)
I know the exact signature of the function.
I already have been able to detour the function, but right now i can't call the real one.
I realize i need to use a trampoline function, I've seen examples online.
the problem is: all those examples show how to detour a windows API function, i need to do the same for a function i get thorough a dll import.
any help would be welcomed
--edit
just to clarify, I have attempted to call the original function by its pointer, but that does not work.
also tried using the method from this stack overflow article
that doesn't even crash but it looks like it goes into to an infinite loop (i assume because in the original function there is a jump to the detoured one)
edit -- solved!
not sure what solved it,
used this as reference.
stopped using getProcadder and instead started using DetourFindFunction instead
cleaned up the code (pretty sure i cleaned out whatever caused the issue)
works,
thanks anyway
I don't use detours(I actually detest it!), but detouring any non hot-patchable function can be done in a generic manner, like so:
Sstep 1:
insert a JMP <your code> at the start of the function, takes 5 bytes, probably a little more to align to the nearest instruction. as an example
the start of the function to hook:
SUB ESP,3C
PUSH EDI
PUSH ESI
//more code
would become:
JMP MyFunction
//more code
one would do this by writing 0xE9 at the first byte then writing the value (function_addr - patch_addr + sizeof(INT_PTR)) in the following DWORD. writing should be done using WriteProcessMemory after setting Read/write/execute permissions with VirtualProtectEx
Step 2:
next, we create an assembly interface:
void __declspec(naked) MyFunc()
{
__asm
{
call Check ;call out filter func
test eax,eax ; test if we let the call through
je _EXIT
sub esp,3c ; its gone through, so we replicate what we overwrote
push edi
push esi
jmp NextExecutionAddress ; now we jump back to the location just after our jump
_EXIT:
retn ; note, this must have the correct stack cleanup
}
}
NextExecutionAddress will need to be filled at run time using ModuleBase + RVA.
To be honest, its way easier, and better(!) to just EAT (Export Address Table) hook the export table of the dll, or IAT (Import Address Table) hook the import tables of whats calling the funcs you want to filter. Detours should have functions for these type of hooks, if not, there are other freely available libs to do it.
The other way would be to use detour to hook every call in the apps using the dll to reroute them to a proxy function in your own code, this has the advantage of allowing one to filter only certain calls, and not everything across a binary(it is possible to do the same using _ReturnAddress, but thats more work), the disadvantage though is capturing the locations to patch(I use ollydbg + a custom patching engine) and it won't work on non-regular calling convention functions(like those made with #pragma aux in Watcom or the optimized calls generated by VC7+).
One important thing to note: if your hooking a multithreaded app, your patches need to be done with the app suspended, or be done attomically use InterlockedExchange, InterlockExchange64 and InterlockedExchangePointer(I use the latter for all IAT/EAT hooks, especially when hooking from a 'third party process')
Looking at the post you link to, the method there is horrible in my opinion, mainly due to the assmebly :P but, how are you calling this pointer you obtain, and how is it obtained?
I have a program which loads DLLs and I need to call one of the non-exported functions it contains. Is there any way I can do this, via searching in a debugger or otherwise? Before anyone asks, yes I have the prototypes and stuff for the functions.
Yes there is, at least sort of, but it isn't a good idea.
In C/C++ all a function pointer is, is an address in memory. So if you somehow where able to find the address of this function you could call it.
Let me ask some questions though, how do you know this DLL contains this function? Do you have the source code? Otherwise I don't know how you could know for certain that this function exists or if it is safe to call. But if you have the source code, then just expose the function. If the DLL writer didn't expose this function, they never expect you to call it and can change/remove the implementation at any time.
Warnings aside, you can find the function address if you have debug symbols or a MAP file you can find the offset in the DLL. If you don't have anything but the DLL, then there is no way to know where that function exists in the DLL - it is not stored in the DLL itself.
Once you have the offset you can then insert that into the code like so:
const DWORD_PTR funcOffset = 0xDEADBEEF;
typedef void (*UnExportedFunc)();
....
void CallUnExportedFunc() {
// This will get the DLL base address (which can vary)
HMODULE hMod = GetModuleHandle("My.dll");
// Calcualte the acutal address
DWORD_PTR funcAddress = (DWORD_PTR)hMod + funcOffset;
// Cast the address to a function poniter
UnExportedFunc func = (UnExportedFunc)funcAddress;
// Call the function
func();
}
Also realize that the offset of this function WILL CHANGE EVERY TIME the DLL is rebuilt so this is very fragile and let me say again, not a good idea.
I realize this question rather is old, but shf301 has the right idea here. The only thing I would add is to implement a pattern search on the target library. If you have IDA or OllyDbg, you can search for the function and view the binary/hex data which surrounds that function's starting address.
In most cases, there will be some sort of binary signature which rarely changes. The signature may hold wildcards which may change between builds, but ultimately there should be at least one successful hit while searching for this pattern, unless extremely drastic changes have occurred between builds (at which point, you could just figure out the new signature for that particular version).
The way that you would implement a binary pattern search is like so:
bool bCompare(const PBYTE pData, const PBYTE bMask, const PCHAR szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask)
return 0;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress, DWORD dwLen, PBYTE bMask, PCHAR szMask)
{
for(DWORD i=0; i<dwLen; i++)
if (bCompare((PBYTE)(dwAddress+i),bMask,szMask))
return (DWORD)(dwAddress+i);
return 0;
}
Example usage:
typedef void (*UnExportedFunc)();
//...
void CallUnExportedFunc()
{
// This will get the DLL base address (which can vary)
HMODULE hMod = GetModuleHandleA( "My.dll" );
// Get module info
MODULEINFO modinfo = { NULL, };
GetModuleInformation( GetCurrentProcess(), hMod, &modinfo, sizeof(modinfo) );
// This will search the module for the address of a given signature
DWORD dwAddress = FindPattern(
hMod, modinfo.SizeOfImage,
(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86",
"xx????xx????xx"
);
// Calculate the acutal address
DWORD_PTR funcAddress = (DWORD_PTR)hMod + dwAddress;
// Cast the address to a function poniter
UnExportedFunc func = (UnExportedFunc)funcAddress;
// Call the function
func();
}
The way that this works is by passing in the base address of the loaded library via GetModuleHandle, specifying the length (in bytes) to search, the binary data to search for, and a mask which specifies which bytes of the binary string are valid ('x') and which are to be overlooked ('?'). The function will then walk through the memory space of the loaded module, searching for a match. In some cases, there may be more than one match and in this case, it's wise to make your signature a little more pronounced to where there is only one match.
Again, you would need to do the initial binary search in a disassembly application in order to know what this signature is, but once you have that then this method should work a little better than manually finding the function offset every time the target is built. Hope this helps.
If the function you want isn't exported, then it won't be in the export address table. Assuming Visual Studio was used to produce this DLL and you have its associated PDB (program database) file, then you can use Microsoft's DIA (debug interface access) APIs to locate the desired function either by name or, approximately, by signature.
Once you have the function (symbol) from the PDB, you will also have its RVA (relative virtual address). You can add the RVA to the loaded module's base address to determine the absolute virtual address in memory where the function is stored. Then, you can make a function call through that address.
Alternatively, if this is just a one-off thing that you need to do (i.e. you don't need a programmatic solution), you can use windbg.exe in the Debugging Tools for Windows toolkit to attach to your process and discover the address of the function you care about. In WinDbg, you can use the x command to "examine symbols" in a module.
For example, you can do x mymodule!*foo* to see all functions whose name contains "foo". As long as you have symbols (PDB) loaded for your module, this will show you the non-export functions as well. Use .hh x to get help on the x command.
Even if you can find the function address, it's not in general safe to call a function created by a compiler that thought it was making a "private" internal-use-only function.
Modern compilers with link-time-optimization enabled may make a specialized version of a function that only does what the specific callers need it to do.
Don't assume that a block of machine code that looks like the function you want actually follows the standard ABI and implements everything the source code says.
In gcc's case, it does use special names for specialized versions of a function that aren't inlined but take advantage of a special case (like constant propagation) from multiple callers.
e.g. in this objdump -drwC output (where -C is demangle):
42944c: e8 cf 13 0e 00 call 50a820
429451: 48 8b 7b 48 mov rdi,QWORD PTR [rbx+0x48]
429455: 48 89 ee mov rsi,rbp
429458: e8 b3 10 0e 00 call 50a510
gcc emits code that calls two different clones of the same function, specialized for two different compile-time-constants. (This is from http://endless-sky.github.io/, which desperately needs LTO because even trivial accessor functions for its XY position class are in Point.cpp, not Point.h, so they can only be inlined by LTO.)
LTO can even make .lto_priv static versions of data: like
mov rcx,QWORD PTR [rip+0x412ff7] # 83dbe0 <_ZN12_GLOBAL__N_116playerGovernmentE.lto_priv.898>
So even if you find a function that looks like what you want, calling it from a new place might violate the assumptions that Link-Time-Optimization took advantage of.
I'm afraid there are no "safe" way to do so if referred library does not explicitly export its object (class/func). Because you will have no idea where is the required object mapped in code memory.
However, by using RE tools, you can find offset for interested object within the library, then add it to any known exported object address to obtain the "real" memory location. After that, prepare a function prototype etc and cast into your local structure for usage.
The most general way to do this (and it's still a bad idea, as everyone else pointed out already) is to scan the DLL code at runtime after it's loaded, and look for a known, unique section of code in that function, and then use code similar to that in shf301's answer to call it. If you know that the DLL won't ever change, than any solution based on determining the offset in the DLL should work.
To find that unique section of code, disassemble the DLL using a disassembler that can show you the machine code in addition to the assembly language mnemonics (I can't think of anything that won't do that) and watch out for call and jmp instructions.
I actually had to do something similar once to apply a binary patch to a DOS exe; it was a bug fix, and the code wasn't under revision control so that was the only way to fix it.
I'd be really curious to know why you need this, by the way.
I don't know assembly so I'm not sure how to go about this.
I have a program which is hooking into another. I have obtained the offset to where the function is located within the hooked program's .exe
#define FuncToCall 0x00447E5D
So now how can I use __asm{} to call that function?
Well short answer is if you do not know assembly you should not be doing this, haha.
But, if you are so intent on wall hacking, I mean, modifying the operation of a legitimate program, you can't just take an address and call it good.
You need to look up the symbol (if in happy linux land) or use sig scanning ( or both D= ) to find the actual function.
Once you do that then its relatively simple, you just need to write a mov and jmp. Assuming you have access to the running process already, and your sig scanner found the right address, this bit of code will get you want you want
mov eax, 0×deadbeef
jmp eax
Now, if this function you want is a class method.. you need to do some more studying. But that bit of assembly will run whatever static function you want.
There is some mess to deal with different calling conventions too, so no commenters try and call me out on that, that is far to advanced for this question.
EDIT:
By the way I do not use call because when using call you have to worry about stack frames and other very messing things. This code will jump to any address and start executing.
If you want to return to your code thats another story, but that WILL get your target function going as long as its the right calling convention, not a class method, etc etc
I think you could also cast that address to a function pointer and call it that way. That might be better.
Thanks for answers, but I figured it out. This is what I'm doing:
#define FuncToCall 0x00447E5D
DWORD myfunc = FuncToCall;
__asm call dword ptr [myfunc];
If it works don't fix it, and by golly it works.
Here is a tricky one:
You can use it with parameters and return value too. It simply forwards everything to the function you intend to call that is given by a pointer (FuncToCall) to the function.
void call_FuncToCall(.......)
{
__asm__
("call label1\n label1:\n"
"pop %eax\n"
"movl FuncToCall, %eax\n"
"leave\n"
"jmp *%eax");
}