Trying to hook to the Present call in Dx12/Dxgi. Is not possible to get the function address via GetProcAddress and some people already figured it out how to obtain the offset directly.
Using Minhook/Kiero (https://github.com/Rebzzel/kiero) it works correctly, say:
typedef HRESULT(APIENTRY* Present12) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
static Present12 oPresent = NULL;
HRESULT APIENTRY ownPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
return oPresent(pSwapChain,SyncInterval, Flags);
}
// On the actual hook part:
void* target = (void*)g_methodsTable[_index];
MH_CreateHook(target, _function, _original);
MH_EnableHook(target);
// Where target is the pointer to the offset where the actual function is located
// _function is the detour function, my ownPresent
// _original will be pointing to the original function
This works as expected, from my own Present:
HRESULT APIENTRY ownPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
return oPresent(pSwapChain,SyncInterval, Flags);
}
All good, the original Present is called at the end.
However, tried to migrate this to Detours and the comparable code would be:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
void* target = (void*)g_methodsTable[_index];
DetourAttach(&(PVOID&)target, _function);
if (_original)
{
*_original = target;
}
DetourTransactionCommit();
It works in the sense that the detour function is being called, however, seems that now the target pointer has the code modified to perform the jump, because now ownPresent calls to ownPresent again, it's recursive.
Not sure if Detours stores a copy of the original code the same way MinHook does, so I can point to the original function and avoid this recursive behavior.
Please let me know if I am using detours incorrectly. Not really sure how to proceed.
Thanks in advance!
Related
I am reading the source code implementation of libext2fs, which is part of the project e2fsprogs used to debug Ext2/3/4 file systems. And came across one confused point about the use of method memcpy as follows.
In the library, it maintains one function ext2fs_get_mem which is used to allocate dynamic memories:
_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
{
void *pp;
pp = malloc(size);
if (!pp)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &pp, sizeof (pp));
return 0;
}
The caller will call it like:
retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs)
In the above case, variable fs is just type of struct struct_ext2_filsys, all right.
The confused point is why the function ext2fs_get_mem need to call memcpy and what's the purpose? Why not directly allocate memory to the pointer void *ptr by malloc?
I'm creating a Linux GUI using GTK3.0 and C and I want to use the same callback for several switches. In order to differentiate the switch that was clicked, I am trying to use the gpointer argument in g_signal_connect, but the callback doesn't seem to receive the right value.
I create the signals this way:
g_signal_connect(led1_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED1");
g_signal_connect(led2_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED2");
And the callback tries to get the gpointer passed:
static void on_gpio_btn_click(GtkWidget *wid, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
...
But when I debug the application, the ptr pointer has the value 0x1, a wrong memory address.
Shouldn't it point to the memory address where the constant string "LED1" is stored?
what am I doing wrong? How can I share the same callback for several widgets? I have 8 switches to control GPIOs and I would prefer to have one callback for all of them instead of creating eight.
Your function signature is wrong: the 2nd argument is the value of the switch's state, as can be found in the documentation of the "state-set" signal. That's also the reason why the value is 1: that's the actual value of TRUE.
In other words, your callback will like this:
static void on_gpio_btn_click(GtkSwitch *swtch, gboolean state, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
// ...
}
In my project, I use to load textures by specifying its file name. Now, I made this function const char* app_dir(std::string fileToAppend); that returns the mains argv[0] and change the application name by the fileToAppend. Since I cannot make the string manipulation easy with a char*, I use the std::string. My texture loader takes a const char* for file name so need to switch back to c_str(), now it generates a sequence of ASCII symbol characters (bug). I already fix the problem by changing the return type of the app_dir() to std::string. But why is that happening?
EDIT
sample code:
//in main I did this
extern std::string app_filepath;
int main(int argc, char** arv) {
app_filepath = argv[0];
//...
}
//on other file
std::string app_filepath;
void remove_exe_name() {
//process the app_filepath to remove the exe name
}
const char* app_dir(std::string fileToAppend) {
string str_app_fp = app_filepath;
return str_app_fp.append(fileToAppend).c_str();
//this is the function the generates the bug
}
I already have the functioning one by changing its return type to std::string as I said earlier.
A big no no :) returning pointer to local objects
return str_app_fp.append(fileToAppend).c_str();
Change your function to
std::string app_dir(const std::string& fileToAppend) {
string str_app_fp = app_filepath + fileToAppend;
return str_app_fp;
}
And on the return value use c_str()
When you using function const char* app_dir(std::string fileToAppend); you get pointer to the memory that allocated on the stack and already deleted when the function ends.
Is there any way to check if the tasklet_init function which initializes a tasklet has failed?
As you would see if you looked at the source (in kernel/softirq.c):
void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data)
{
t->next = NULL;
t->state = 0;
atomic_set(&t->count, 0);
t->func = func;
t->data = data;
}
all the function does is set some structure members, so there is no possible way tasklet_init can fail.
In general if a kernel function returns void then you don't need to check if it succeeded or not. And of course the nice thing about the Linux kernel is that you can always refer to the source and see if there are any ways something can fail.
On Windows, several arguments are passed to the DllMain constructor:
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
);
From hinstDLL I can get the fully qualified file name of the DLL itself using GetModuleFileName():
LPTSTR str = new TCHAR[256];
int libNameLength = GetModuleFileName(hinstDLL, str, 256);
delete[] str;
In the example above, str now contains the full name of the DLL just loaded, e.g., C:\Windows\System32\MyFile.dll.
On Linux, no arguments are passed to the shared object constructor:
void `__attribute__` ((constructor)) on_load(void);
How do I get the full name of the DLL in this case? Extra credit if your solution works on Mac, too. :-)
I think the dladdr function might do what you want. From the man page:
The function dladdr() takes a function pointer and tries to resolve
name and file where it is located. Information is stored in the
Dl_info structure:
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
If no symbol matching addr could be found, then dli_sname and
dli_saddr are set to NULL.
dladdr() returns 0 on error, and non-zero on success.
So you just give it a function pointer (like the address of the constructor itself), and it will give you the filename and a bunch of other information. Here's some sample code:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
__attribute__((constructor))
void on_load(void) {
Dl_info dl_info;
dladdr(on_load, &dl_info);
fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}
EDIT: It looks like this function exists on OS X, too, with the same semantics.
One supremely ugly and horrible way to do this is to look through /proc/pid/maps and look for the mapping that encompasses the address of the on_load function being executed.