/* Inject.cpp --
This file is part of the "ZImport 0.1".
Copyright (C) 2006-2007 Ashkbiz Danehkar
All Rights Reserved.
zero Dump library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYRIGHT.TXT.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Ashkbiz Danehkar
<ashkbiz@yahoo.com>
*/
#include "stdafx.h"
#include <stdio.h>
#include "Inject.h"
#include "ntundoc.h"
#include "loader.h"
static HANDLE hProcess;
static HANDLE hThread;
BOOL KillShellAbout(DWORD dwProcessId, DWORD dwThreadId);
void StrUpper(PCHAR str);
int RedirectAPI(PCHAR pMem, DWORD API_voffset, DWORD NEW_voffset);
void* ReturnToBytePtr(void* FuncName, DWORD findstr);
void GetLdrCode(PCHAR &pLdr, DWORD &rsize);
//----------------------------------------------------------------
BOOL KillShellAbout(DWORD dwProcessId, DWORD dwThreadId)
{
CONTEXT Context;
LDT_ENTRY SelEntry;
DWORD dwFSBase;
PTEB pteb = new TEB;
PPEB ppeb = new PEB;
PIMAGE_DOS_HEADER pimage_dos_header = new IMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS pimage_nt_headers = new IMAGE_NT_HEADERS;
PCHAR pMem = NULL;
PCHAR pLdr = NULL;
DWORD dwBytes, OldProtect, dwImageBase, dwRedirectMem, dwShellAbout, Ldr_rsize;
HMODULE hModule;
Ldr_rsize = 0;
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessId );
hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, dwThreadId);
SuspendThread(hThread);
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread,&Context);
// Calculate the base address of FS
GetThreadSelectorEntry(hThread, Context.SegFs, &SelEntry);
dwFSBase = ( SelEntry.HighWord.Bits.BaseHi << 24) |
(SelEntry.HighWord.Bits.BaseMid << 16) |
SelEntry.BaseLow;
//pteb=(PTEB)dwFSBase;
VirtualProtectEx( hProcess, (LPVOID)dwFSBase, sizeof(TEB), PAGE_READWRITE, &OldProtect);
ReadProcessMemory( hProcess, (LPCVOID)dwFSBase, pteb, sizeof(TEB), &dwBytes);
VirtualProtectEx( hProcess, (LPVOID)pteb->Peb, sizeof(PEB), PAGE_READWRITE, &OldProtect);
ReadProcessMemory( hProcess, (LPCVOID)pteb->Peb, ppeb, sizeof(PEB), &dwBytes);
dwImageBase = (DWORD)ppeb->ImageBaseAddress;
ReadProcessMemory( hProcess, (LPCVOID)dwImageBase, pimage_dos_header, sizeof(IMAGE_DOS_HEADER), &dwBytes);
ReadProcessMemory( hProcess, (LPCVOID)(dwImageBase+pimage_dos_header->e_lfanew), pimage_nt_headers, sizeof(IMAGE_NT_HEADERS), &dwBytes);
pMem = (PCHAR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, pimage_nt_headers->OptionalHeader.SizeOfImage);
ReadProcessMemory( hProcess,
(LPCVOID)(dwImageBase),
pMem,
pimage_nt_headers->OptionalHeader.SizeOfImage,
&dwBytes);
hModule = LoadLibrary("Shell32.dll");
dwShellAbout= (DWORD)GetProcAddress(hModule, "ShellAboutW");
dwRedirectMem = (DWORD)VirtualAllocEx( hProcess, NULL, 0x01D000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
RedirectAPI(pMem, dwShellAbout, dwRedirectMem);
VirtualProtectEx( hProcess,
(LPVOID)(dwImageBase),
pimage_nt_headers->OptionalHeader.SizeOfImage,
PAGE_EXECUTE_READWRITE,
&OldProtect);
WriteProcessMemory( hProcess,
(LPVOID)(dwImageBase),
pMem,
pimage_nt_headers->OptionalHeader.SizeOfImage,
&dwBytes);
GetLdrCode(pLdr, Ldr_rsize);
WriteProcessMemory( hProcess,
(LPVOID)(dwRedirectMem),
pLdr,
Ldr_rsize,
&dwBytes);
ResumeThread(hThread);
GlobalFree(pLdr);
GlobalFree(pMem);
delete pimage_nt_headers;
delete pimage_dos_header;
delete ppeb;
delete pteb;
return TRUE;
}
//----------------------------------------------------------------
void StrUpper(PCHAR str)
{
int i;
int l = (int) strlen(str);
for(i=0; i<l; i++)
{
str[i]=toupper(str[i]);
}
}
//---------------------------------------------------------
int RedirectAPI(PCHAR pMem, DWORD API_voffset, DWORD NEW_voffset)
{
PCHAR pThunk;
PCHAR pHintName;
DWORD dwAPIaddress;
PCHAR pDllName;
DWORD dwImportDirectory;
DWORD dwAPI;
PCHAR pImageBase = pMem;
//----------------------------------------
PIMAGE_IMPORT_DESCRIPTOR pimage_import_descriptor;
PIMAGE_THUNK_DATA pimage_thunk_data;
//----------------------------------------
PIMAGE_DOS_HEADER pimage_dos_header;
PIMAGE_NT_HEADERS pimage_nt_headers;
pimage_dos_header = PIMAGE_DOS_HEADER(pImageBase);
pimage_nt_headers = (PIMAGE_NT_HEADERS)(pImageBase+pimage_dos_header->e_lfanew);
//----------------------------------------
dwImportDirectory=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if(dwImportDirectory==0)
{
return -1;
}
//----------------------------------------
pimage_import_descriptor=(PIMAGE_IMPORT_DESCRIPTOR)(pImageBase+dwImportDirectory);
//----------------------------------------
while(pimage_import_descriptor->Name!=0)
{
pThunk=pImageBase+pimage_import_descriptor->FirstThunk;
pHintName=pImageBase;
if(pimage_import_descriptor->OriginalFirstThunk!=0)
{
pHintName+=pimage_import_descriptor->OriginalFirstThunk;
}
else
{
pHintName+=pimage_import_descriptor->FirstThunk;
}
pDllName=pImageBase+pimage_import_descriptor->Name;
StrUpper(pDllName);
if(strcmp(pDllName,"SHELL32.DLL")==0)
{
pimage_thunk_data=PIMAGE_THUNK_DATA(pHintName);
while(pimage_thunk_data->u1.AddressOfData!=0)
{
//----------------------------------------
memcpy(&dwAPI, pThunk, 4);
if(dwAPI==API_voffset)
{
memcpy(pThunk, &NEW_voffset, 4);
return 0;
}
//----------------------------------------
pThunk+=4;
pHintName+=4;
pimage_thunk_data++;
}
}
pimage_import_descriptor++;
}
//----------------------------------------
return -1;
}
//================================================================
//----------------------------------------------------------------
// Function: ReturnToBytePtr
// void* FuncNum: Function Name
// DWORD findstr: String to find
//
// This code was written by FEUERRADER [AHTeam], Thanks him!
void* ReturnToBytePtr(void* FuncName, DWORD findstr)
{
void* tmpd;
__asm
{
mov eax, FuncName
jmp df
hjg: inc eax
df: mov ebx, [eax]
cmp ebx, findstr
jnz hjg
mov tmpd, eax
}
return tmpd;
}
//================================================================
void GetLdrCode(PCHAR &pLdr, DWORD &rsize)
{
HMODULE hModule;
DWORD dwMessageBox;
PCHAR ch_temp;
DWORD dwCodeSize;
ch_temp=(PCHAR)DWORD(ReturnToBytePtr(DynLoader, DYN_LOADER_START_MAGIC))+4;
dwCodeSize=DWORD(ReturnToBytePtr(DynLoader, DYN_LOADER_END_MAGIC))-DWORD(ch_temp);
rsize= dwCodeSize;
pLdr = (PCHAR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwCodeSize);
memcpy(pLdr, ch_temp, dwCodeSize);
ch_temp=(PCHAR)ReturnToBytePtr(pLdr, DYN_LOADER_START_DATA1);
hModule = LoadLibrary("User32.dll");
dwMessageBox= (DWORD)GetProcAddress(hModule, "MessageBoxA");
memcpy(ch_temp+4, &dwMessageBox, 4);
}