SetWindowsHookEx injection failed on release mode but worked on debug mode - c

I'm writing a program which monitors Keystrokes of a target process using SetWindowsHookEx. (IDE: Visual Studio 2013)Here's an overview of my program:
Obtain a HWND of the target process using FindWindow().
If HWND is valid, obtain the process id using GetWindowThreadProcessId()
Obtain a thread id by traversing the thread list with CreateToolhelp32Snapshot(TH32CS_THREAD)
Call SetWindowsHookEx().
Actual code:
//obtain the window handle
HWND hwnd = FindWindowA(NULL, "A valid title");
DWORD pid = 0;
//obtain the process id.
GetWindowThreadProcessId(hwnd, &pid);
//obtain the thread id.
DWORD threadId = GetThreadId(pid);
printf("Injecting to Process: %d Thread: %d\n", pid, threadId);
HMODULE hDll = LoadLibraryA("TestDLL.dll");
if (hDll == INVALID_HANDLE_VALUE)
{
printf("LoadLibrary() failed! %d!\n", GetLastError());
return 0;
}
HOOKPROC hookproc = (HOOKPROC)GetProcAddress(hDll, "KeyboardProc");
if (!hookproc)
{
printf("GetProcAddress() failed\n");
return 0;
}
HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC, hookproc, hDll, threadId);
if (!hook)
{
printf("SetWindowsHookEx() failed! %d\n", GetLastError());
return 0;
}
//post a message. This will trigger the hook and cause the target process
//to load my dll. Actual key monitoring code is inside the dll.
printf("SendMessage() returns:%d", SendMessage(hwnd, WM_NULL, 0, 0));
printf("Success!\n");
UnhookWindowsHookEx(hook);
getchar();
Under Debug mode, the output shows:
Injecting to process 4052 Thread:460
SendMessage() returns:0
Success!
A simple analysis shows that the target process did load my dll. Which means the program works. However, under release mode, the output is the same but dll is not loaded into the target process. I tried this multiple times with restarting target process each time. But still doesn't work.
How do I resolve this problem?

When you say "under Debug mode" - does it mean that you are debugging inside VS?
If so, my guess that the problem might be in permission set - you can run VS with elevated permissions or under another user/group. Try to run your release version of the app in Admin mode. Otherwise it would be a security flaw if any process can inject code into any another process.

Related

Vlc library fails when I use fork() in C and Ubuntu

I can't understand why I keep to get this error:
ALSA lib pcm_dmix.c:1108:(snd_pcm_dmix_open) unable to open slave
[00005617d3cf0630] alsa audio output error: cannot open ALSA device "default": No such file or directory
[00005617d3cf0630] main audio output error: Audio output failed
[00005617d3cf0630] main audio output error: The audio device "default" could not be used:
No such file or directory.
[00005617d3cf0630] main audio output error: module not functional
[00007f2ce803b080] main decoder error: failed to create audio output
when I try to reproduce a mp3 file with a fork().
The code works pretty fine if I use it outside the fork().
It looks like the child process can't access the hardware sound card?
I really can't understand how can I solve the problem.
pid = fork();
printf("il pid: %d\n", pid);
if (pid == 0) {
libvlc_instance_t *inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
// load the vlc engine
inst = libvlc_new(0, NULL);
printf("apro il file \n");
// create a new item
m = libvlc_media_new_path(inst, "/home/robodyne/Downloads/file.mp3");
// create a media play playing environment
mp = libvlc_media_player_new_from_media(m);
// no need to keep the media now
libvlc_media_release(m);
// play the media_player
libvlc_media_player_play(mp);
sleep(10);
// stop playing
libvlc_media_player_stop(mp);
// free the media_player
libvlc_media_player_release(mp);
libvlc_release(inst);
exit(0);
}
EDIT1: I'm trying to use THREADS
Following the suggestion of Antti Haapala, I tried to use threads instead of fork() but when I call "pthread_cancel(thread);", the mp3 doesn't stop.
This is my new code:
pthread_t thread;
void *wait(void*)
{
libvlc_instance_t *inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
// load the vlc engine
inst = libvlc_new(0, NULL);
printf("apro il file %d\n", inst);
// create a new item
m = libvlc_media_new_path(inst, "/home/robodyne/Downloads/file.mp3");
// create a media play playing environment
mp = libvlc_media_player_new_from_media(m);
// no need to keep the media now
libvlc_media_release(m);
// play the media_player
libvlc_media_player_play(mp);
sleep(10);
// stop playing
libvlc_media_player_stop(mp);
// free the media_player
libvlc_media_player_release(mp);
libvlc_release(inst);
printf("Done.\n");
}
SecondPage::SecondPage(wxWindow* parent,wxWindowID id)
{
//(*Initialize(SecondPage)
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
SetClientSize(wxSize(1314,769));
SetBackgroundColour(wxColour(175,253,202));
// some code from wxwidgets removed
m_reboot.Bind(wxEVT_TIMER, &SecondPage::Reboot, this);
if (get_day_of_year() == 2 || get_day_of_year() == 4){
secco->Show();
}
pthread_create(&thread, NULL, wait, NULL);
}
void SecondPage::OnplasticaClick(wxCommandEvent& event)
{
pthread_cancel(thread);
thirdpage = new ThirdPage(nullptr, 2);
thirdpage->selezione="plastica";
strcpy(thirdpage->codice_fiscale, codice_fiscale);
thirdpage->tipologia_rifiuto->SetLabel(thirdpage->selezione);
thirdpage->Refresh();
thirdpage->Update();
thirdpage->m_reboot.StartOnce(600000);
thirdpage->Show(true);
this->Hide();
}
A fork is never safe in a multi-threaded program, except when immediately followed by exit or exec. It is not clear what you do before calling fork but you do something non-trivial for sure, otherwise there would not be any difference between this forked version and the one that does not fork.
Unfortunately there are really 3 alternatives:
fork really early in the program execution, before any libraries are used,
use threads
execute another program - for example the same executable with different arguments so that it knows it is the child in the forked process.
I think this problem is most likely solved in newer versions like pulseaudio.
Let's define the problem. If you open alsa and then create a fork, allocated resources of alsa shared both by parent and child. This is the big problem for dmix. To avoid this problem, you should either have a separate application where you will do the sound issues, or you should not fork without closing alsa.

How to make a process unable to exit by hook sys_exit_group and sys_kill

I'm working with Android 8.1 Pixel2 XL phone.
I have hooked the sys_call_table and have replaced the syscalls with my own functions using the kernel module.
I want to make an application unable to quit.
I'm trying to invalidate an application's sys_exit_group and sys_kill.
What should I do in my own function.
I want to debug an application, but it turns on anti-debugging. So I want to hook the system call
I have tried direct return, but It wasn't work. System will call sys_kill again.But this time, I can't get the application's uid from its pid.
asmlinkage long my_sys_kill(pid_t pid, int sig)
{
char buff[MAX_PATH] = {0};
kuid_t uid = current->cred->uid;
int target_uid = get_uid_from_pid(pid);
if (target_uid == targetuid)
{
printk(KERN_DEBUG "#Tsingxing: kill hooked uid is %d pid is %d, tragetuid is %d, packagename: %s\n",uid.val,pid, target_uid, buff);
return 0;
}
printk(KERN_DEBUG "#Tsingxing:kill called uid is %d,pid is %d, traget_uid is %d\n",uid.val,pid,target_uid);
return origin_sys_kill(pid, sig);
}
asmlinkage long my_sys_exit_group(int error_code)
{
char buff[MAX_PATH] = {0};
kuid_t uid = current->cred->uid;
long tgid = current -> tgid;
long pid = current->pid;
int target_uid = get_uid_from_pid(pid);
if (uid.val == targetuid || target_uid == targetuid)
{
printk(KERN_DEBUG "#Tsingxing:exit group hooked, pid is %ld\n",pid);
return 0;
}
return origin_sys_exit_group(error_code);
}
I have solved this problem. I mixed sys_call_table and compat_sys_call_table. The Target application is using compat_sys_call_table but I'm using the __NR_xxx. I solved the problem using __NR_compat_xxx method. Just return direct in compat_sys_call_exit_group.
At a very high level, this can't work. When an application calls _Exit (possibly/likely at the end of exit), it has no path to any further code to be run. These functions are normally even marked _Noreturn, meaning that the compiler does not leave the registers/calling stack frame in a meaningful state where resumption of execution could occur. Even if it did, the program itself at the source level is not prepared to continue execution.
If the function somehow returned, the next step would be runaway wrong code execution, likely leading to arbitrary code execution under the control of an attacker if the application had been processing untrusted input of any kind.
In practice, the libc side implementation of the exit and _Exit functions likely hardens against kernel bugs (yes, what you're asking for is a bug) whereby SYS_exit_group fails to exit. I haven't verified other implementations lately but I know mine in musl do this, because it's cheap and the alternative is very dangerous.

How to execute threads in a DLL in C

I created a DLL that is running 3 worker threads, and the main thread is in a loop waiting for the threads to complete. The threads get created, but no execution to the threads is done.
I have tried setting MessageBox functions inside the function that gets created with CreateThread() but the box does not appear. I have also tried to debug and the return value from CreateThread() is valid so the thread gets created.
BOOL WINAPI DllMain() {
main();
return 1;
}
int main() {
HANDLE h1, h2, h3;
h1 = CreateThread(first)...
h2 = CreateThread(second)...
h3 = CreateThread(third)...
WaitForSingleObject(h3, INFINITE);
return 1;
}
first() {
MessageBoxA("print some stuff");
return;
}
I have included some pseudocode of what my layout looks like. I am unable to provide the real code due to the sensitivity of it. However this is what is happening. I use LoadLibrary in another project that loads this .DLL. The DLL gets loaded and DllMain is executed. It then calls my main function which creates 3 threads. Each thread is created. But what is inside of the thread does not execute.
EDIT:
// dllmain.cpp : Defines the entry point for the DLL application.
#include <Windows.h>
void mb() {
MessageBoxW(0, L"AAAAAAAAAAAAAAAAAAAAAAAAA", L"AAAAAAAAAAAAAAAAAAAAAAa", 1);
}
void create() {
HANDLE han;
DWORD threadId;
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
}
BOOL APIENTRY DllMain() {
create();
return 1;
}
[MS.Docs]: DllMain entry point (emphasis is mine) states:
Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components. Conversely, calling functions such as these during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.
[MS.Docs]: MessageBox function resides in User32.dll, so it's Undefined Behavior (meaning that in different scenarios, it might work, it might work faulty, or it might crash).
Also, as #RbMm noticed, WaitForSingleObject doesn't belong there. I'm not sure about CreateThread either (but I couldn't find any official doc to confirm / infirm it).
Just out of curiosity, could you add a printf("main called.\n"); in main, to see how many times it is called?
because in general case DLL can be unloaded, need add reference to DLL - for it will be not unloaded until thread, which use it code executed. this can be done by call GetModuleHandleEx - increments the module's reference count unless GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT is specified. when thread exit - we dereference DLL code by call FreeLibraryAndExitThread. wait for all threads exit in most case not need. so code, inside dll can be next
ULONG WINAPI DemoThread(void*)
{
MessageBoxW(0, L"text", L"caption", MB_OK);
// dereference dlll and exit thread
FreeLibraryAndExitThread((HMODULE)&__ImageBase, 0);
}
void someFnInDll()
{
HMODULE hmod;
// add reference to dll, because thread will be use it
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCWSTR)&__ImageBase, &hmod))
{
if (HANDLE hThread = CreateThread(0, 0, DemoThread, 0, 0, 0))
{
CloseHandle(hThread);
}
else
{
// dereference dll if thread create fail
FreeLibrary(hmod);
}
}
}
wait inside dll entry point is wrong, because we hold here process wide critical section. if we wait for thread exit - this wait always deadlock - thread before exit (and start) try enter this critical section, but can not because we wait for him here. so we hold critical section and wait for thread(s), but threads(s) wait when we exit from this critical section. deadlock

KERNEL_APC_PENDING_DURING_EXIT BSOD

I am setting a PLOAD_IMAGE_NOTIFY_ROUTINE to detect a specific image name and if there's a match, then terminate it. I am getting a KERNEL_APC_PENDING_DURING_EXIT BSOD though. The BSOD is happening somewhere in my KillProcess function which simply just opens a kernel handle with ObOpenObjectByPointer then calls ZwTerminateProcess on that handle.
What could be wrong? The code works fine outside the routine. Do I have to post it? I am getting a BSOD in my PLOAD_IMAGE_NOTIFY_ROUTINE when I call KillProcess.
Here is my KillProcess function:
NTSTATUS KillProcess(HANDLE ProcessId)
{
PEPROCESS Process;
HANDLE newProcessHandle = NULL;
NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &Process);
do
{
if (!NT_SUCCESS(status))
{
#ifdef DEBUGPRINT
DbgPrint("Process with id %d does not exist\n", ProcessId);
#endif
break;
}
if (NT_SUCCESS(status = ObOpenObjectByPointer(
Process,
OBJ_KERNEL_HANDLE,
NULL,
PROCESS_TERMINATE,
*PsProcessType,
KernelMode,
&newProcessHandle
)))
{
if (newProcessHandle != NULL)
{
status = ZwTerminateProcess(newProcessHandle, 0);
ZwClose(newProcessHandle);
}
else
{
ObDereferenceObject(Process);
break;
}
if (NT_SUCCESS(status))
{
#ifdef DEBUGPRINT
DbgPrint("Successfully killed process with id %d\n", ProcessId);
#endif
}
else
{
#ifdef DEBUGPRINT
DbgPrint("Failed to kill process with id %d\n", ProcessId);
#endif
}
}
else
{
#ifdef DEBUGPRINT
DbgPrint("Failed to open process with id %d\n", ProcessId);
#endif
}
ObDereferenceObject(Process);
} while (FALSE);
return status;
}
The documentation for PsSetLoadImageNotifyRoutine says:
When the main executable image for a newly created process is loaded, the load-image notify routine runs in the context of the new process.
(It also seems likely that when a DLL is loaded, the call is made in the context of the process loading the DLL.)
So from the sounds of it, you are terminating the process whose context you are running in. What's more, you're doing it at a particularly vulnerable point, during a callback for an image load operation. It is not surprising that this causes trouble.
The documentation for ZwTerminateProcess implies that a driver can terminate the current process, provided that it ensures that resources have been freed from the kernel stack, but I don't think that applies in this situation. (Also, I don't know how you'd go about doing that.)
It might instead be possible to suspend the process, and terminate it later from a system thread.
The problem is I was trying to terminate the process in its own context which lead to a BSOD.
Solution:
Create a global variable holding the pid
Set the global variable
In a system thread, check if the global variable has changed
terminate the process

Run process and wait for it AND its child processes to end [duplicate]

Is it possible to wait for all processes launched by a child process in Windows? I can't modify the child or grandchild processes.
Specifically, here's what I want to do. My process launches uninstallA.exe. The process uninistallA.exe launches uninstallB.exe and immediately exits, and uninstallB.exe runs for a while. I'd like to wait for uninstallB.exe to exit so that I can know when the uninstall is finished.
Create a Job Object with CreateJobObject. Use CreateProcess to start UninstallA.exe in a suspended state. Assign that new process to your job object with AssignProcessToJobObject. Start UninstallA.exe running by calling ResumeThread on the handle of the thread you got back from CreateProcess.
Then the hard part: wait for the job object to complete its execution. Unfortunately, this is quite a bit more complex than anybody would reasonably hope for. The basic idea is that you create an I/O completion port, then you create the object object, associate it with the I/O completion port, and finally wait on the I/O completion port (getting its status with GetQueuedCompletionStatus). Raymond Chen has a demonstration (and explanation of how this came about) on his blog.
Here's a technique that, while not infallible, can be useful if for some reason you can't use a job object. The idea is to create an anonymous pipe and let the child process inherit the handle to the write end of the pipe.
Typically, grandchild processes will also inherit the write end of the pipe. In particular, processes launched by cmd.exe (e.g., from a batch file) will inherit handles.
Once the child process has exited, the parent process closes its handle to the write end of the pipe, and then attempts to read from the pipe. Since nobody is writing to the pipe, the read operation will block indefinitely. (Of course you can use threads or asynchronous I/O if you want to keep doing stuff while waiting for the grandchildren.)
When (and only when) the last handle to the write end of the pipe is closed, the write end of the pipe is automatically destroyed. This breaks the pipe and the read operation completes and reports an ERROR_BROKEN_PIPE failure.
I've been using this code (and earlier versions of the same code) in production for a number of years.
// pwatch.c
//
// Written in 2011 by Harry Johnston, University of Waikato, New Zealand.
// This code has been placed in the public domain. It may be freely
// used, modified, and distributed. However it is provided with no
// warranty, either express or implied.
//
// Launches a process with an inherited pipe handle,
// and doesn't exit until (a) the process has exited
// and (b) all instances of the pipe handle have been closed.
//
// This effectively waits for any child processes to exit,
// PROVIDED the child processes were created with handle
// inheritance enabled. This is usually but not always
// true.
//
// In particular if you launch a command shell (cmd.exe)
// any commands launched from that command shell will be
// waited on.
#include <windows.h>
#include <stdio.h>
void error(const wchar_t * message, DWORD err) {
wchar_t msg[512];
swprintf_s(msg, sizeof(msg)/sizeof(*msg), message, err);
printf("pwatch: %ws\n", msg);
MessageBox(NULL, msg, L"Error in pwatch utility", MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
ExitProcess(err);
}
int main(int argc, char ** argv) {
LPWSTR lpCmdLine = GetCommandLine();
wchar_t ch;
DWORD dw, returncode;
HANDLE piperead, pipewrite;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
char buffer[1];
while (ch = *(lpCmdLine++)) {
if (ch == '"') while (ch = *(lpCmdLine++)) if (ch == '"') break;
if (ch == ' ') break;
}
while (*lpCmdLine == ' ') lpCmdLine++;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&piperead, &pipewrite, &sa, 1)) error(L"Unable to create pipes: %u", GetLastError());
GetStartupInfo(&si);
if (!CreateProcess(NULL, lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
error(L"Error %u creating process.", GetLastError());
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) error(L"Error %u waiting for process.", GetLastError());
if (!GetExitCodeProcess(pi.hProcess, &returncode)) error(L"Error %u getting exit code.", GetLastError());
CloseHandle(pipewrite);
if (ReadFile(piperead, buffer, 1, &dw, NULL)) {
error(L"Unexpected data received from pipe; bug in application being watched?", ERROR_INVALID_HANDLE);
}
dw = GetLastError();
if (dw != ERROR_BROKEN_PIPE) error(L"Unexpected error %u reading from pipe.", dw);
return returncode;
}
There is not a generic way to wait for all grandchildren but for your specific case you may be able to hack something together. You know you are looking for a specific process instance. I would first wait for uninstallA.exe to exit (using WaitForSingleObject) because at that point you know that uninstallB.exe has been started. Then use EnumProcesses and GetProcessImageFileName from PSAPI to find the running uninstallB.exe instance. If you don't find it you know it has already finished, otherwise you can wait for it.
An additional complication is that if you need to support versions of Windows older than XP you can't use GetProcessImageFileName, and for Windows NT you can't use PSAPI at all. For Windows 2000 you can use GetModuleFileNameEx but it has some caveats that mean it might fail sometimes (check docs). If you have to support NT then look up Toolhelp32.
Yes this is super ugly.
Use a named mutex.
One possibility is to install Cygwin and then use the ps command to watch for the grandchild to exit

Resources