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);
Related
In mfc code,
Declare as follow
CWinThread* _pThread[5];
DWORD _ThreadArg[5] = { HIGHEST_THREAD, // 0x00
ABOVE_AVE_THREAD, // 0x3F
NORMAL_THREAD, // 0x7F
BELOW_AVE_THREAD, // 0xBF
LOWEST_THREAD // 0xFF
};
int i;
for (i= 0; i< 5; i++)
{
_pThread[i] = AfxBeginThread(ThreadFunc,
&_ThreadArg[i],
THREAD_PRIORITY_NORMAL,
0,
//CREATE_SUSPENDED,
NULL,
NULL);
//_pThread[i]->ResumeThread();
}
// setup relative priority of threads
_pThread[0]->SetThreadPriority(THREAD_PRIORITY_HIGHEST);
_pThread[1]->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
_pThread[2]->SetThreadPriority(THREAD_PRIORITY_NORMAL);
_pThread[3]->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
_pThread[4]->SetThreadPriority(THREAD_PRIORITY_LOWEST);
use same thread function
UINT CThreadPoolDlg::ThreadFuncTh1(LPVOID ThreadArg)
{
DWORD dwArg = *(DWORD*)ThreadArg;
//txtTh[0].SetWindowTextW(_T("23"));
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->SetWindowText(_T("1"));
return 0;
}
How do I check which thread is in use in same function?
I get a answer as follow
_pThread[0] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
NULL,
NULL);
_pThread[1] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
_pThread[2] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
the thread function is declare as follow
UINT CThreadPoolDlg::ThreadFunc(LPVOID ThreadArg)
{
CThreadPoolDlg* dwArg = (CThreadPoolDlg*)ThreadArg;
DWORD dThread = GetCurrentThreadId();
//txtTh[0].SetWindowTextW(_T("23"));
while(1)
{
CString strTemp;
if(dThread == dwArg->_pThread[0]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->SetWindowText(strTemp);
if(n > 5)
{
::SendMessage(dwArg->GetSafeHwnd(), OWM_MYMETHOD, 0, 0);
//dwArg->_pThread[1]->ResumeThread();
}
}
if(dThread == dwArg->_pThread[1]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD2)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD2)->SetWindowText(strTemp);
if(n > 5)
{
dwArg->_pThread[2]->ResumeThread();
}
}
if(dThread == dwArg->_pThread[2]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD3)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD3)->SetWindowText(strTemp);
}
Sleep(500);
}
return 0;
}
Just look at the
DWORD dThread = GetCurrentThreadId();
dThread == dwArg->_pThread[1]->m_nThreadID
then I will get current thread id...
I have injected one of my dll in many process.What I want to do is call the function in that dll from my application in all the process in which it is loaded. I used following codes.It works fine in windows vista+ OS but it get failed at line GetProcAddress() in windows xp...why this is happening please help me out. Thanks in advance.
const TCHAR * pszDllName = _T("MyDll.dll");
void CallProcessFunc( DWORD processID,LPCSTR funcName)
{
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE |
PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD,
FALSE, processID );
if(hProcess == NULL)
return;
HMODULE hMods[1024];
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, hMods, sizeof(hMods), &cbNeeded) )
{
for (int i = 0; i < (int)(cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)) == FALSE)
continue;
if(_tcsstr(szModName, pszDllName) == NULL)
continue;
LPTHREAD_START_ROUTINE lpRoutine = (LPTHREAD_START_ROUTINE) ::GetProcAddress(hMods[i], funcName);// here it get failed in windows xp
if(lpRoutine == NULL)
continue;
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpRoutine, NULL, NULL, NULL);
if(hRemoteThread == NULL)
continue;
WaitForSingleObject(hRemoteThread, INFINITE);
DWORD ret = 0;
GetExitCodeThread(hRemoteThread, &ret);
CloseHandle(hRemoteThread);
break;
}
}
CloseHandle( hProcess );
}
void fnCallRemoteFuntion()
{
LPCSTR fuctName = "NotifyDll";
DWORD aProcesses[1024], cbNeeded = 0;
EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded );
int cProcesses = (int)(cbNeeded / sizeof(DWORD));
for (int i = 0; i < cProcesses; i++ )
{
if( aProcesses[i] == 0 )
continue;
CallProcessFunc(aProcesses[i], fuctName);
}
}
I got my solution from an article for which link is given.
http://www.codeproject.com/Tips/139349/Getting-the-address-of-a-function-in-a-DLL-loaded
i was using GetProcAddress function which was incorrect Bcoz it is giving proc address in current process not in remote process and my need was getting proc address in remote thread,which is explain in above link.
I create a file:
m_fileHandle = CreateFileA(
m_pszFilename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
Then write to it:
const BOOL bSuccess = WriteFile(
m_fileHandle,
buffer,
dataSize,
&tempBytesWritten,
NULL );
When I start the program, WriteFile fails and GetLastError() returns error 87.
I read that WriteFile on a file created with flag FILE_FLAG_NO_BUFFERING fails when dataSize is not a multiple of hard disk sector size.
If that is the reason for the error, then why does the code work fine when I debug in Visual Studio Express 2012?
Solution was here: File Buffering https://msdn.microsoft.com/en-us/library/windows/desktop/cc644950%28v=vs.85%29.aspx
Working code:
#include "stdafx.h"
#include "assert.h"
#include <iostream>
#include <Windows.h>
#include <comutil.h>
using namespace std;
namespace{
unsigned long tempBytesWritten = 0;
HANDLE m_fileHandle;
char m_pszFilename[_MAX_PATH] = "";
// Create a temporary file for benchmark
int createFile()
{
WCHAR tempPath[MAX_PATH];
GetTempPath(_countof(tempPath), tempPath);
_bstr_t p(tempPath);
const char* c = p;
strcpy(m_pszFilename, c);
strcat(m_pszFilename, "testRawFile.raw");
cout << "Writing to " << m_pszFilename << endl;
m_fileHandle = CreateFileA(
m_pszFilename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
if (m_fileHandle == INVALID_HANDLE_VALUE)
{
assert( false );
}
return 0;
}
}
DWORD DetectSectorSize( WCHAR * devName, PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR pAlignmentDescriptor)
{
DWORD Bytes = 0;
BOOL bReturn = FALSE;
DWORD Error = NO_ERROR;
STORAGE_PROPERTY_QUERY Query;
ZeroMemory(&Query, sizeof(Query));
HANDLE hFile = CreateFileW( devName,
STANDARD_RIGHTS_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile==INVALID_HANDLE_VALUE) {
wprintf(L" hFile==INVALID_HANDLE_VALUE. GetLastError() returns %lu.\n", Error=GetLastError());
return Error;
}
Query.QueryType = PropertyStandardQuery;
Query.PropertyId = StorageAccessAlignmentProperty;
bReturn = DeviceIoControl( hFile,
IOCTL_STORAGE_QUERY_PROPERTY,
&Query,
sizeof(STORAGE_PROPERTY_QUERY),
pAlignmentDescriptor,
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR),
&Bytes,
NULL);
if (bReturn == FALSE) {
wprintf(L" bReturn==FALSE. GetLastError() returns %lu.\n", Error=GetLastError());
}
CloseHandle(hFile);
return Error;
}
int main()
{
unsigned int dataSize = 2000;
DWORD Error = NO_ERROR;
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR Alignment = {0};
// WCHAR szDisk[] = L"\\\\.\\PhysicalDrive0";
WCHAR szDisk[] = L"\\\\.\\C:";
Error = DetectSectorSize(szDisk, &Alignment);
if (Error) {
wprintf(L"Error %lu encountered while querying alignment.\n", Error);
return Error;
}
wprintf(L"Disk %s Properties\n", (WCHAR*) szDisk);
if (Alignment.BytesPerLogicalSector < Alignment.BytesPerPhysicalSector) {
wprintf(L" Emulated sector size is %lu bytes.\n", Alignment.BytesPerLogicalSector);
}
wprintf(L" Physical sector size is %lu bytes.\n", Alignment.BytesPerPhysicalSector);
dataSize = ((unsigned int)(dataSize + Alignment.BytesPerPhysicalSector - 1)/Alignment.BytesPerPhysicalSector) * Alignment.BytesPerPhysicalSector;
// Allocate buffer for file
unsigned char *buffer = new unsigned char[dataSize];
// Create file to write to
if ( createFile() != 0 )
{
printf("There was error creating the files... press Enter to exit.");
getchar();
return -1;
}
const BOOL bSuccess = WriteFile(m_fileHandle, buffer, dataSize, &tempBytesWritten, NULL );
if (!bSuccess)
{
cout << "Write failed with error " << GetLastError() << endl;
}
// clean up and remove file
CloseHandle(m_fileHandle);
wchar_t wtext[_MAX_PATH];
mbstowcs(wtext, m_pszFilename, strlen(m_pszFilename)+1);
DeleteFile(wtext);
return 0;
}
The following program goes into a deadlock. Can anyone please tell me why?
#include<cstdlib>
#include<windows.h>
#include<iostream>
using namespace std;
class CircularQueue
{
public:
CircularQueue(int s)
{
size = s;
array = (int*)malloc(sizeof(int) * size);
head = tail = -1;
InitializeCriticalSection(&critical_section);
}
CircularQueue(void)
{
size = default_size;
array = (int*)malloc(sizeof(int) * size);
head = tail = -1;
InitializeCriticalSection(&critical_section);
}
void initialize(int s)
{
EnterCriticalSection(&critical_section);
size = s;
array = (int*)realloc(array, sizeof(int) * size);
head = tail = -1;
LeaveCriticalSection(&critical_section);
}
void enqueue(int n)
{
EnterCriticalSection(&critical_section);
tail = (tail + 1) % size;
array[tail] = n;
LeaveCriticalSection(&critical_section);
}
int dequeue(void)
{
EnterCriticalSection(&critical_section);
head = (head + 1) % size;
return array[head];
LeaveCriticalSection(&critical_section);
}
private:
int *array;
int size;
int head, tail;
CRITICAL_SECTION critical_section;
bool initialized;
static const int default_size = 10;
};
DWORD WINAPI thread1(LPVOID param)
{
CircularQueue* cqueue = (CircularQueue*)param;
cqueue->enqueue(2);
cout << cqueue->dequeue() << endl;
return 0;
}
DWORD WINAPI thread2(LPVOID param)
{
CircularQueue* cqueue = (CircularQueue*)param;
cqueue->enqueue(3);
cout << cqueue->dequeue() << endl;
return 0;
}
int main(void)
{
HANDLE thread1_handle;
HANDLE thread2_handle;
CircularQueue cqueue;
HANDLE array[2];
thread1_handle = CreateThread(NULL, 0, thread1, &cqueue, 0, NULL);
thread2_handle = CreateThread(NULL, 0, thread2, &cqueue, 0, NULL);
array[0] = thread1_handle;
array[1] = thread2_handle;
WaitForMultipleObjects(1, array, TRUE, INFINITE);
CloseHandle(thread1_handle);
CloseHandle(thread2_handle);
printf("end\n");
return 0;
}
In dequeue(), you have a return statement before the LeaveCriticalSection() call. If you had compiler warnings turned up higher, it would probably have told you about this!
I'm getting a weird error. I implemented these two functions:
int flag_and_sleep(volatile unsigned int *flag)
{
int res = 0;
(*flag) = 1;
res = syscall(__NR_futex, flag, FUTEX_WAIT, 1, NULL, NULL, 0);
if(0 == res && (0 != (*flag)))
die("0 == res && (0 != (*flag))");
return 0;
}
int wake_up_if_any(volatile unsigned int *flag)
{
if(1 == (*flag))
{
(*flag) = 0;
return syscall(__NR_futex, flag, FUTEX_WAKE, 1, NULL, NULL, 0);
}
return 0;
}
and test them by running two Posix threads:
static void die(const char *msg)
{
fprintf(stderr, "%s %u %lu %lu\n", msg, thread1_waits, thread1_count, thread2_count);
_exit( 1 );
}
volatile unsigned int thread1_waits = 0;
void* threadf1(void *p)
{
int res = 0;
while( 1 )
{
res = flag_and_sleep( &thread1_waits );
thread1_count++;
}
return NULL;
}
void* threadf2(void *p)
{
int res = 0;
while( 1 )
{
res = wake_up_if_any( &thread1_waits );
thread2_count++;
}
return NULL;
}
After thread2 has had a million or so iterations, I get the assert fire on me:
./a.out
0 == res && (0 != (*flag)) 1 261129 1094433
This means that the syscall - and thereby do_futex() - returned 0. Man says it should only do so if woken up by a do_futex(WAKE) call. But then before I do a WAKE call, I set the flag to 0. Here it appears that flag is still 1.
This is Intel, which means strong memory model. So if in thread1 I see results from a syscall in thread2, I must also see the results of the write in thread 2 which was before the call.
Flag and all pointers to it are volatile, so I don't see how gcc could fail to read the correct value.
I'm baffled.
Thanks!
the race happens when thread 1 goes the full cycle and re-enters WAIT call when thread 2 goes from
(*flag) = 0;
to
return syscall(__NR_futex, flag, FUTEX_WAKE, 1, NULL, NULL, 0);
So the test is faulty.