Print function call stack in fatal handler of the duktape - duktape

I would like to print the function call stack in the fatal handler of the duktape:
void duktape_fatal(void *d, const char *m)
{
int line, pc, level;
const char *fnName = NULL;
printf("JSE fatal: %s!\n", (m ? m : ""));
level = -1;
while (1)
{
duk_inspect_callstack_entry(ctx, level);
if (duk_is_undefined(ctx, -1))
{
duk_pop(ctx);
break;
}
duk_get_prop_string(ctx, -1, "function");
fnName = duk_to_string(ctx, -1);
duk_pop(ctx);
duk_get_prop_string(ctx, -1, "lineNumber");
line = duk_to_int(ctx, -1);
duk_pop(ctx);
duk_get_prop_string(ctx, -3, "pc");
pc = duk_to_int(ctx, -1);
duk_pop(ctx);
duk_pop(ctx);
printf("Trace %i,%i: %s\n", pc, line, fnName);
level--;
}
while (1)
{
;
}
}
And this is an example JS script that triggers the fatal error:
function test3() {
var b = 1;
print(a);
}
function test2() {
test3();
}
function test() {
test2();
}
test();
In this example, the fatal function will print only the fault lineNumber, but not the call stack. Any help is appreciated.

Related

Futex Error in C application that is using mutex and epoll

I am running epoll to process network connection. Everything is working perfectly I think.
Now i am trying to connect to the Postgresql Database from the child process. I have 4 child process.
Sometimes when i try to connect to the server. It hangs.
Sometimes i get this error
fserver: tpp.c:84: __pthread_tpp_change_priority: Assertion `new_prio
Would appreciate it if someone would be able to advice on my code. Thanks
If i remove the Postgresql Connection code , the problem disappears.
/******CHILD PROCESS **************/
void childProcess()
{
const char conninfo[] = "postgresql://postgres#localhost?port=5432&dbname=ram&password=xxx";
PGconn *conn = PQconnectdb(conninfo);
const ConnStatusType connStatusType = PQstatus(conn);
if (connStatusType == CONNECTION_BAD) {
printf("pg connection not OK");
if (conn) {
PQfinish(conn);
}
exit(1);
} else {
printf("pg connection OK");
}
int efd = epoll_create1(0);
if(efd == -1)
{
perror("Epoll Creation Failed\n");
}
nonblocksocket(&p2c_var);
struct epoll_event event0;
event0.data.fd = p2c_var;
event0.events = EPOLLIN | EPOLLET;
if(epoll_ctl(efd,EPOLL_CTL_ADD,p2c_var,&event0) == -1)
{
perror("First Failed to add file descriptor to epoll watch list\n");
}
nonblocksocket(&c2p_var);
struct epoll_event event1;
event1.data.fd = c2p_var;
event1.events = EPOLLOUT | EPOLLET;
if(epoll_ctl(efd,EPOLL_CTL_ADD,c2p_var,&event1) == -1)
{
perror("Second Failed to add file descriptor to epoll watch list\n");
}
struct epoll_event *ttlevents;
ttlevents = calloc(MAXEVENTS, sizeof(event0));
int head = 0,tail = 0;
pthread_mutex_t buflock;
pthread_mutex_t fdlock;
int bufhead=0,buftail=0;
struct fifoarr *fifoptr = (struct fifoarr *) calloc(QSIZE,sizeof(struct fifoarr));
int co = 0;
char st[1050];
memset(st,0,sizeof(st));
st[0] = 1;
while(1)
{
int eventcount = epoll_wait(efd,ttlevents,MAXEVENTS,-1);
for(int i =0;i<eventcount;i++)
{
if ((ttlevents[i].events & EPOLLERR) || (ttlevents[i].events & EPOLLHUP))
{
/* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */
fprintf (stderr, "epoll error\n");
close (ttlevents[i].data.fd);
continue;
}
if(ttlevents[i].events & EPOLLOUT)
{
if(ttlevents[i].data.fd == c2p_var)
{
pthread_mutex_lock(&buflock);
int bufval = popfd(&bufhead,&buftail);
if(bufval != -1)
{
write(c2p_var,fifoptr[bufval].buffer,sizeof(fifoptr[bufval].buffer));
}
pthread_mutex_unlock(&buflock);
}
}
if(ttlevents[i].events & EPOLLIN)
{
if(ttlevents[i].data.fd == p2c_var)
{
char buffer[1050];
while(1)
{
memset(buffer,0,sizeof(buffer));
int c = read(ttlevents[i].data.fd,buffer,sizeof(buffer));
if(c == -1)
{
if(errno == EAGAIN)
{
printf("Completed Reading From Parent Process\n");
break;
}
}
if(c == 0)
{
printf("Parent terminated Connection.\n");
break;
}
if(buffer[0] != 1)
{
pthread_mutex_lock(&buflock);
int bufval = pushfd(&bufhead);
if(bufval != -1)
{ memset(fifoptr[bufval].buffer,0,sizeof(fifoptr[bufval].buffer)); memcpy(fifoptr[bufval].buffer,buffer,sizeof(buffer));
// processRequest(fifoptr[bufval].buffer,conn);
write(c2p_var,&st,sizeof(st));
}
pthread_mutex_unlock(&buflock);
}//buffer[0]
}//While
}
}//if epollin
} //for
}//while(1)
PQfinish(conn);
}
The program tends to hang.
Well it is working now.
It seems that mutex is the cause of the problem.
Thanks for all that looked at my code.

linux kernel module data compression

linux 2.6
I am writing a LKM. I need to compress and decompress on the fly many different chunks of text.
I prefer to call kernel api, avoiding to include and compile external libraries.
Are there kernel Api to compress and decompress memory ?
source and destination buffers can be both in kernel memory or one in kernel the other in user space.
Not sure why kernel.org excludes the compression part.
One may need to mimic from its official skcipher example, in which the procedure is like below:
tfm = crypto_alloc_tfm("yourAlg",
CRYPTO_TFM_MODE_yourAlg);
req = skcipher_request_alloc(tfm, GFP_KERNEL);
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
test_tfm_cb,
result);
crypto_cipher_setkey(tfm, key, keylength);
crypto_cipher_encrypt(tfm, &scatterlist,
numlists);
tfm_request_free(req);
crypto_free_tfm(tfm);
Notice kernel now is moving to async, however callback is not shown in latest header file.
/**
* acomp_request_set_callback() -- Sets an asynchronous callback
*
* Callback will be called when an asynchronous operation on a given
* request is finished.
*
* #req: request that the callback will be set for
* #flgs: specify for instance if the operation may backlog
* #cmlp: callback which will be called
* #data: private data used by the caller
*/
static inline void acomp_request_set_callback(struct acomp_req *req,
u32 flgs,
crypto_completion_t cmpl,
void *data)
{
req->base.complete = cmpl;
req->base.data = data;
req->base.flags = flgs;
}
Example code:
struct comp_testvec tv, int mode;
int ilen = tv.inlen;
char *str_input = tv.input;
int olen = tv.outlen;
char *str_output = tv.output;
struct scatterlist sg[2];
struct scatterlist sg2[2];
char *input;
char *output;
char *input2;
char *output2;
struct acomp_req *req;
struct crypto_acomp *tfm;
struct tcrypt_result result;
int ret = 0;
input = kmalloc(ilen, GFP_KERNEL);
output = kmalloc(olen, GFP_KERNEL);
input2 = kmalloc(olen, GFP_KERNEL);
output2 = kmalloc(ilen, GFP_KERNEL);
char *driver = tv.alg;
tfm = crypto_alloc_acomp(driver, CRYPTO_ALG_TYPE_ACOMPRESS,
CRYPTO_ALG_TYPE_ACOMPRESS_MASK);
if (IS_ERR(tfm)) {
printk(KERN_ERR "alg: acomp: Failed to load transform for "
"%s: %ld\n", driver, PTR_ERR(tfm));
return PTR_ERR(tfm);
}
init_completion(&result.completion);
if (mode == 0)
{
//zip
memcpy(input,str_input,ilen);
printk("input => %s\n", input);
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input, ilen, false);
printk("alg => %s\n",driver);
sg_init_one(&sg[0], input, ilen);
sg_init_one(&sg[1], output, COMP_BUF_SIZE);
req = acomp_request_alloc(tfm);
if(!req)
{
printk("error req = null\n");
crypto_free_acomp(tfm);
return -1;
}
acomp_request_set_params(req, &sg[0], &sg[1], ilen, COMP_BUF_SIZE);
acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
tcrypt_complete, &result);
ret = crypto_acomp_compress(req);
if(ret == -EINPROGRESS || ret == -EBUSY)
{
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err)))
{
reinit_completion(&result.completion);
}
}
else if(ret == 0)
{
printk("succ\n");
}
else
{
printk("error ret = %d\n",ret);
goto out;
}
printk("compress => \n");
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output, olen, false);
} else if (mode == 1) {
//unzip
memcpy(input2,str_output,olen);
printk("input => \n");
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input2, olen, false);
char *driver = tv.alg;
printk("alg => %s\n",driver);
//sg init
sg_init_one(&sg2[0], input2, ilen);
sg_init_one(&sg2[1], output2, COMP_BUF_SIZE);
req = acomp_request_alloc(tfm);
if(!req)
{
printk("error req = null\n");
crypto_free_acomp(tfm);
return -1;
}
acomp_request_set_params(req, &sg2[0], &sg2[1], ilen, COMP_BUF_SIZE);
acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
tcrypt_complete, &result);
ret = crypto_acomp_decompress(req);
if(ret == -EINPROGRESS || ret == -EBUSY)
{
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err)))
{
reinit_completion(&result.completion);
}
}
else if(ret == 0)
{
printk("succ\n");
}
else
{
printk("error ret = %d\n",ret);
goto out;
}
printk("decompress => %s\n", output2);
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output2, ilen, false);

Remote Code injection in Win 7 SP 1 using NtCreateThreadEx API

I am trying to learn how to inject code into a running process using NtCreateThreadEx. I found few tutorials online and tried the code shown below which basically tries to inject a piece of code to a a running notepad.exe. Code injection to notepad.exe was successful; however, this program crashes just after injection (i.e., after calling funNtCreateThreadEx) throwing following error:
Run-Time Check Failure #2 - Stack around the variable 'temp2' was corrupted.
Could someone help me explaining why I am getting this error? I tried to Google about this error and figured out its something related to memory overflow. However, I don't see any memory overflow in this following code. Please let me know what could be the reason for the above error. Thank you so much for your time.
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter);
typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx)
(
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN DWORD StackZeroBits,
IN DWORD SizeOfStackCommit,
IN DWORD SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
struct NtCreateThreadExBuffer
{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter) {
HMODULE modNtDll = LoadLibrary(L"ntdll.dll");
if (!modNtDll) {
std::cout << "Error loading ntdll.dll" << std::endl;
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)GetProcAddress(modNtDll, "NtCreateThreadEx");
if (!funNtCreateThreadEx) {
std::cout << "Error loading NtCreateThreadEx()" << std::endl;
return 0;
}
NtCreateThreadExBuffer ntbuffer;
memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
// ntbuffer.Unknown8 = 0;
HANDLE hThread;
NTSTATUS status = funNtCreateThreadEx(
&hThread,
0x1FFFFF,
NULL,
process,
(LPTHREAD_START_ROUTINE)Start,
lpParameter,
FALSE, //start instantly
0, //null
0, //null
0, //null
&ntbuffer
);
return hThread;
}
int main()
{
int res = -1;
res = privileges(); //get all required privileges
DWORD pid = getPid(L"notepad.exe");
if (pid == 0)
return PROCESS_NOT_FOUND; //error
HANDLE p;
p = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (p == NULL) return OPEN_PROCESS_FAILED; //error
char * mytext = "Hello by CodeCave!";
char * mycaption = "Injection result";
PARAMETERS data; //let's fill in a PARAMETERS struct
HMODULE user32 = LoadLibrary(L"User32.dll");
data.MessageBoxInj = (DWORD)GetProcAddress(user32, "MessageBoxA");
strcpy_s(data.text, mytext);
strcpy_s(data.caption, mycaption);
data.buttons = MB_OKCANCEL | MB_ICONQUESTION;
//Writing funtion to notepad memory
DWORD size_myFunc = 0x8000; //Creating more memory than required
LPVOID MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(p, MyFuncAddress, (void*)myFunc, 0x1000, NULL);
//Parameters to the function to notepad's memory
LPVOID DataAddress = VirtualAllocEx(p, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(p, DataAddress, &data, sizeof(PARAMETERS), NULL);
//invokes injected function
HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress);
if (thread != 0) {
//injection completed, not we can wait it to end and free the memory
}
return 0;
}
static DWORD myFunc(PARAMETERS * myparam) {
MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
switch (result) {
case IDOK:
//your code
break;
case IDCANCEL:
//your code
break;
}
return 0;
}
int privileges() {
HANDLE Token;
TOKEN_PRIVILEGES tp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL) == 0) {
return 1; //FAIL
}
else {
return 0; //SUCCESS
}
}
return 1;
}
typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);
struct PARAMETERS {
DWORD MessageBoxInj;
char text[50];
char caption[25];
int buttons;
};
DWORD myFunc(PARAMETERS * myparam);

How to pass the pointer of a memory buffer created by calloc to a sub function?

Here is my code:
I have to dynamically create some memory for the string Str1 and pass its pointer to the other two functions in a recursive manner. The code compiles but when it enters Function2 it generates an exception saying that cannot write c[i], bad pointer? (i.e. it does not write to Str1)
What am i doing wrong?
void Function1(void)
{
char *Str1;
Str1 = calloc(25, sizeof(char));
pFileIn = fopen("in.txt", "r");
pFileOut = fopen("out.txt", "w+");
if (pFileIn==NULL) printf("Error opening file");
else
{
while (Function2(pFileIn, Str1))
{
if (! Function3(pFileOut, Str1))
{
fseek(pFileOut, 0, SEEK_END);
fprintf(pFileOut, "%s", Str1);
rewind(pFileOut);
}
}
fclose(pFileIn);
fclose(pFileOut);
}
int Function2(FILE* f, char * c)
{
int i=0;
do
{
c[i] = fgetc(f);
if (c[i]==EOF)
return FALSE;
} while (c[i++]!='\n');
c[i] = '\0';
return TRUE;
}
int Function3(FILE* f, char * c)
{
char *Str2;
Str2 = calloc(25, sizeof(char));
while (Function2(f, Str2))
{
if (strcmp(c, Str2)==0)
return TRUE;
}
rewind(f);
return FALSE;
}

How to compare string variable to constant string in visual c++?

I have this piece of code:
#include "stdafx.h"
#include "afx.h"
...
char * connectionType;
...
int readParameters() {
...
//hFile is a file handler previously initialized
result = readParameter(hFile, connectionType);
if (strcmp(connectionType, "3") == 0) {
//do something
} else {
//do other thing
}
...
}
int readParameter(HANDLE hFile, OUT char * buffer) {
BOOL bResult = true;
BOOL continueLine = true;
char inBuffer[1];
DWORD bytesToRead = 1;
DWORD bytesRead = 0;
OVERLAPPED stOverlapped = {0};
char parameter[256] = {};
int counter = 0;
while (continueLine) {
bResult = ReadFile(hFile, inBuffer, sizeof(char), &bytesRead, &stOverlapped);
if (!bResult) {
return 0;
} else if (inBuffer[0] == '\n' || bytesRead == 0) {
continueLine = false;
} else {
parameter[counter] = inBuffer[0];
counter++;
if (bResult && bytesRead == 0) {
continueLinea = false;
}
}
}
parameter[counter] = '\0';
memcpy(buffer, parameter, 256);
return 1;
}
By debugging, I know that the connectionType attribute ends up being a null terminated string "3", but the strcmp method keeps returning 3328 (>0). Is there a problem because "3" is a constant? What might be the problem?
I realized what was the problem with the code. The problem was that connectionType, whose value was a null terminated string "3", was in fact different to the line read from the file, which was actually a "3" plus a carriage return plus a null.
After I added that consideration to the code, my problem was solved.

Resources