I am writing a LKM that hooks a function with a custom function.
To achieve this I am modifying the function's prologue with
mov rax, <custom_func_addr> // Intel syntax.
jmp rax
The exact opcode is : "\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe0" // 8 '\x00' are replaced with actual address.
The code works fine.say I hook vfs_read(), It works accordingly.
The is one case I have observed in which hooking fails :
void foo(char *func) {
unsigned long addr = get_sym_addr(func); // gets the address of function.
DEBUG("function %s addr : %lu\n", func, addr);
hook((void*)addr, &test_func_hooked); // hook it with custom function.
void (*test_func_orig) (int) = addr; // get ptr to the function.
test_func_orig(20); // call through func ptr.
test_func(10); // call function directly.
}
// defined in same file.
void test_func(int a) {
printk("a = %d\n", a);
}
However Hooking happens properly when function gets called using func ptr.
and, If I directly call the function as - test_func(10), hook is not called.
Is there anything I am missing here ? I have tested the module by hooking vfs_read() , whenever a 'read' comes on any file, hook get called. Only this particular case where function to hook is in the same file, It is not working.
Related
My lua function looks like below. The parameter "scandate" is pased from c++ to the lua function. The printed output of the first line shows the date, and thereafter, any operation on the string indicates the string suddenly became null or empty.
function DoCustomLookup(wkItem,wkfId,wkevid,lookupTableID,scandate,lookuptext,lookupval,evtAlertText,newvalue,xtraFld1,xtraFld2,xtraFld3,xtraFld4,newStatus,newStatusDesc,errFlags)
local rslt = "Script error"
print (scandate)
local scYY = scandate.sub(1,4)
local scMM = scandate.sub(7,2)
local scDD = scandate.sub(10,2)
print (scYY)
print (scMM)
print (scDD)
local scandt = #scandate
print (scandt)
scYY,scMM, scDD = scandate.match("(%d+)%-(%d+)%-(%d+)%s.+")
...
end
Here is the console output:
2015-12-10 01:00:02
0
19
Workflow script error. Line :17: bad argument #2 to 'match' (string expected, got no value)
So it appears to me that the string simply vanishes in thin air.
Can someone please explain what is going on and how I can keep the string? The strange thing is that substrings do not work, but the string length still prints 19. Then match also keeps failing (That is why I tried the substr as alternative)
Here is my code calling it from c++. You will notice I copy the date to a temporary buffer. I thought maybe the std::string.c_str() maybe got out of scope, but it did not change wheter I pass the date as std::string or from a c buffer.
bool LuaScript::DoCustomLookup(int wkItem, int wkfId, int wkevid, const int lookupTableID, const std::string scantime,
const std::string& lookuptext, const std::string& lookupval, const std::string evtAlertText,
std::string& newvalue,
const std::string xtraFld1, const std::string xtraFld2, const std::string xtraFld3, const std::string xtraFld4,
int& newStatus, std::string& newStatusDesc, AlertFlags& errFlags, std::string& errMsg)
{
errMsg = "";
char **date**[50];
sprintf(date, "%s", scantime.c_str());
lua_getglobal(L, "DoCustomLookup"); // get function
lua_pushinteger(L, wkItem); // push parameter on call stack
lua_pushinteger(L, wkfId); // push parameter on call stack
lua_pushinteger(L, wkevid); // push parameter on call stack
lua_pushinteger(L, lookupTableID); // push parameter on call stack
lua_pushstring(L, **date**); // push parameter on call stack
lua_pushstring(L, lookuptext.c_str()); // push parameter on call stack
lua_pushstring(L, lookupval.c_str()); // push parameter on call stack
lua_pushstring(L, evtAlertText.c_str()); // push parameter on call stack
lua_pushstring(L, newvalue.c_str()); // push parameter on call stack
lua_pushstring(L, xtraFld1.c_str()); // push parameter on call stack
lua_pushstring(L, xtraFld2.c_str()); // push parameter on call stack
lua_pushstring(L, xtraFld3.c_str()); // push parameter on call stack
lua_pushstring(L, xtraFld4.c_str()); // push parameter on call stack
lua_pushinteger(L, newStatus); // push parameter on call stack
lua_pushstring(L, newStatusDesc.c_str()); // push parameter on call stack
lua_pushinteger(L, errFlags); // push parameter on call stack
int rslt = lua_pcall(L, 16, 1, 0);
Thank you
I can read the status of my laptop lid by reading /proc/acpi/button/lid/LID0/state file. Now I want to read it from kernel module.
I found the source file drivers/acpi/button.c in kernel source. But still I didn't understand how to use it. It exporting acpi_lid_notifier_register, acpi_lid_notifier_unregiste and acpi_lid_open functions.
How to write a module for lid state?
acpi_lid_open returns 0 (closed), 1 (open), or a negative error number (unsupported).
To use the notifier, you would define a callback function and a notifier block in your module:
static int yourmodule_lid_notify(struct notifier_block *nb, unsigned long val, void *unused) {
// Whatever you wanted to do here
}
static struct notifier_block lid_notifier;
// Somewhere in a function, likely your module init function:
lid_notifier.notifier_call = yourmodule_lid_notify;
if (acpi_lid_notifier_register(&lid_notifier)) {
// TODO: Handle the failure here
}
// TODO: Unregister the notifier when your module is unloaded:
acpi_lid_notifier_unregister(&lid_notifier);
I'm currently creating a network application that uses the usrsctp library on windows and I'm having an odd problem with parameters appearing as null when they shouldn't be on a callback function. I'm not sure if this is a specific usrsctp issue or something I'm doing wrong so I wanted to check here first.
When creating a new sctp socket you pass a function as one of the parameters that you want to be called when data is received as shown in the code below
static int receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
if (data == NULL) {
printf("receive_cb - Data NULL, closing socket...\n");
done = 1;
usrsctp_close(sock);
}
else {
_write(_fileno(stdout), data, datalen);
free(data);
}
return (1);
}
...
//Create SCTP socket
if ((sctpsock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) == NULL) {
perror("usrsctp_socket");
return -1;
}
Tracing through the library I can see that before the call back is called all the parameters are correct
As soon as I step into it they become null
I've no idea what would cause this, the callback function was taken straight from the official examples so nothing should be wrong there.
Ok, worked out the issue, it seems that the parameter before 'union sctp_sockstore addr' was causing the stack to be pushed by 0x1c and moving the rest of the parameters away from where they should be. I've never come across this issue before but changing the parameter to a pointer fixed it.
I had the same Issue, in my case the reason was a missing define for INET.
Since the size of 'union sctp_sockstore' depends on this define.
So you have to ensure, that you use the same defines as you used when compiling the library.
I am overloading "malloc" by pre-loading a library. In this custom "malloc", i am using environment variable to distinguish my program to use my custom "malloc" from the general "malloc".
The problem is that, after several "mallocs" the program gets stuck inside getenv() call. I am not able to figure out why the program is getting stuck inside it.
The code is the following:
void* PerfTrackMallocInterposition::Malloc(size_t size) {
// Malloc with statistics
pthread_mutex_lock(&fgPTMutex);
char *checkCDBEnd=NULL;
static const char* CDBEndEnv = "checkCDBEnd";
checkCDBEnd = getenv(CDBEndEnv); //program gets stuck here
if(checkCDBEnd!=NULL)
{
if(checkCDBEnd[0]=='1')
{
if(size>1024)
{
void *result = Alloc(size); //Call to custom malloc
pthread_mutex_unlock(&fgPTMutex);
return result;
}
}
}
void* result = (*fPMalloc)(size); //call to normal malloc
pthread_mutex_unlock(&fgPTMutex);
return result;
}
I also get a bus error at same position while using this library with vim editor.
Please help me.
Thank You
Are you sure the program gets stuck on the getenv() call? I would be more suspicious of the mutexes: pthread_mutex_lock(&fgPTMutex); will block if another thread holds the mutex
I am building an audio player that plays '.wav' files and I have a problem with the callback function called from waveOutOpen() API.
Opening the output audio device for playback:
MMRESULT mRes = waveOutOpen(m_hWO,WAVE_MAPPER,&wFmt,(DWORD)&waveOutProc,(DWORD)this, CALLBACK_FUNCTION);
Implementation of callback function:
void CPlayWave::waveOutProc(HWAVEOUT m_hWO,UINT uMsg,DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
MMRESULT mmRes;
CPlayWave *pPW = (CPlayWave*)dwInstance;
switch(uMsg)
{
case MM_WOM_DONE: //playback finished
mmRes = waveOutUnprepareHeader(m_hWO, &pPW->m_WHdr, sizeof(WAVEHDR));
if(mmRes!=MMSYSERR_NOERROR)
{
//error handling
.....
}
mmRes = waveOutClose(m_hWO);
if(mmRes!=MMSYSERR_NOERROR)
{
//error handling
.....
}
AfxMessageBox("Finished playing the file");
m_bPlay = FALSE; //boolean flag used for pausing
break;
case WIM_DATA:
//for recording completion
break;
}
}
The problem is the MM_WOM_DONE never occurs and the callback function is never called after the playback of the file is completed. If a thread has to be used instead of callback function, can someone give me a simple example on how to use a callback thread(haven't found on net).
Also waveOutReset() documentation suggests that it closes all the buffers and returns to the system, so for handling the Stop-button in my application, I used the waveOutReset() function but, this causing the application to freeze. Why is this happening? Is there any alternative method to stop playing while buffer is still in queue for playback.
Callback function probably can not be a method of your class CPlayWave itself. It must be simple function out of your class with requested prototype.
void CALLBACK waveOutProc(HWAVEOUT m_hWO, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
...
}
It must be, of course, declared/defined before you call waveOutOpen(). In addition, function name is pointer itself and ampersand & is not needed. Thus calling waveOutOpen() should be:
MMRESULT mRes = waveOutOpen(m_hWO, WAVE_MAPPER, &wFmt, (DWORD_PTR) waveOutProc, (DWORD_PTR) this, CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
Also you there are only few system functions you can call from waveOutProc:
"Applications should not call any system-defined functions from inside a callback function, except for EnterCriticalSection, LeaveCriticalSection, midiOutLongMsg, midiOutShortMsg, OutputDebugString, PostMessage, PostThreadMessage, SetEvent, timeGetSystemTime, timeGetTime, timeKillEvent, and timeSetEvent. Calling other wave functions will cause deadlock."
So calling funcitons like AfxMessageBox or waveOutUnprepareHeader might be cause terrible issues.