Новичок
Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.7.2006
Репутация: нет Всего: нет
|
Незнаю........Уже весь мозг себе этой проблемой замучил.И так первоначально это было VC++ консольное приложение - я пытаюсь переделать это в BC++ библиотеку вот код pedll.cpp Код | #include <vcl.h> // used to inject shell code into the target executable #include <windows.h> #include <stdio.h> #include <conio.h> #include "BPET.h" // target EP code magic values // where to write OEP-PEP distance in the self (inside of shell) #define MAGIC_PEP_OEP_DISTANCE 0x06
// shell magic values // magic byte of the data indentifying sequence #define MAGIC_BYTE 0xFF // magic length of the magic sequence #define MAGIC_LENGTH 0x05 #define IMAGE_DIRECTORY_ENTRY_RESERVE 15
#define P(a, b) fprintf(o, a, b) #define S(a) fprintf(o, a) #pragma hdrstop //--------------------------------------------------------------------------- // Important note about DLL memory management when your DLL uses the // static version of the RunTime Library: // // If your DLL exports any functions that pass String objects (or structs/ // classes containing nested Strings) as parameter or function results, // you will need to add the library MEMMGR.LIB to both the DLL project and // any other projects that use the DLL. You will also need to use MEMMGR.LIB // if any other projects which use the DLL will be performing new or delete // operations on any non-TObject-derived classes which are exported from the // DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling // EXE's to use the BORLNDMM.DLL as their memory manager. In these cases, // the file BORLNDMM.DLL should be deployed along with your DLL. // // To avoid using BORLNDMM.DLL, pass string information using "char *" or // ShortString parameters. // // If your DLL uses the dynamic version of the RTL, you do not need to // explicitly add MEMMGR.LIB as this will be done implicitly for you //---------------------------------------------------------------------------
#pragma argsused char *image_directory[] = { " IMAGE_DIRECTORY_ENTRY_EXPORT = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_IMPORT = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_RESOURCE = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_EXCEPTION = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_SECURITY = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_BASERELOC = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_DEBUG = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_TLS = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_IAT = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 0x%0.8X : 0x%0.8X\n", " IMAGE_DIRECTORY_ENTRY_RESERVE = 0x%0.8X : 0x%0.8X\n" }; extern "C" __declspec(dllexport)DWORD hash_string(char *string) { __asm { push ebp mov ebp, esp push esi push edx push ecx mov esi, [ebp + 8] xor edx, edx // hash xor eax, eax cld next_char: xor eax, eax lodsb test eax, eax jz done
mov ecx, edx rol ecx, 7 ror edx, (32 - 7) or edx, ecx xor edx, eax jmp next_char done: mov eax, edx pop ecx pop edx pop esi mov esp, ebp pop ebp ret 4 } } extern "C" __declspec(dllexport)DWORD findMagicSequence(LPBYTE start, DWORD len) { DWORD i; DWORD j; BYTE found;
for (i = 0; i < (len - MAGIC_LENGTH); i++) { found = 1; for (j = 0; j < MAGIC_LENGTH; j++) { if (((BYTE) start[i + j]) != MAGIC_BYTE) { found = 0; break; } } if (found != 0) break; }
if (found == 0) return 0; // not found
return i; } extern "C" __declspec(dllexport)DWORD GetFileSizeByName(char *name) { HANDLE file; DWORD size;
file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (file == INVALID_HANDLE_VALUE) return 0;
size = GetFileSize(file, NULL); CloseHandle(file); return size; } extern "C" __declspec(dllexport)int encrypt(LPBYTE mem, DWORD mem_size) { DWORD i; BYTE hash_byte; BYTE found = 0;
__asm { cld mov esi, mem lodsb mov hash_byte, al } printf("hash_char = 0x%0.2X\n", (DWORD) hash_byte);
if ((i = findMagicSequence(mem, mem_size)) == 0) { printf("findMagicSequence failed!\n"; return 1; } mem_size -= i + MAGIC_LENGTH + 8; printf("mem size to crypt = %d\n", mem_size);
__asm { cld mov edi, mem add edi, i add edi, MAGIC_LENGTH // preserve 0xFF.. secquence for future restore add edi, 8 // preserve 2 important dword value //mov al, NOP //mov ecx, MAGIC_LENGTH //rep stosb // erase 0xFF... sequence with nops
mov esi, edi mov ecx, mem_size mov ah, hash_byte again: lodsb xor al, ah xor al, cl stosb loop again }
return 0; } extern "C" __declspec(dllexport)int decrypt(LPBYTE mem, DWORD mem_size) { DWORD i; BYTE hash_byte; BYTE found = 0;
__asm { cld mov esi, mem lodsb mov hash_byte, al } printf("hash_char = 0x%0.2X\n", (DWORD) hash_byte);
if ((i = findMagicSequence(mem, mem_size)) == 0) { printf("findMagicSequence failed!\n"; return 1; } mem_size -= i + MAGIC_LENGTH + 8; printf("mem size to crypt = %d\n", mem_size);
__asm { cld mov esi, mem add esi, i add esi, MAGIC_LENGTH // preserve 0xFF.. sequence for future restore lodsd // get size of original code lodsd // delta to the crypted stuff
//mov al, NOP //mov ecx, MAGIC_LENGTH //rep stosb // erase 0xFF... sequence with nops
mov edi, esi mov ecx, mem_size mov ah, hash_byte again: lodsb xor al, cl xor al, ah stosb loop again }
return 0; } extern "C" __declspec(dllexport) int modify(LPVOID mem, DWORD secRawOffset, DWORD shellSize, DWORD EPOffset, DWORD secVA, char *password) { DWORD magicOffset; DWORD OEPRO; // OEP raw offset in the file DWORD OEPRVA; // OEP RVA DWORD distance; // RVA(shellSection) - RVA(OEP) DWORD pass_hash; PIMAGE_SECTION_HEADER ish; // target's EP section info
pass_hash = hash_string(password == NULL ? "adult" : password); printf("password hash = 0x%0.8X\n", pass_hash);
// NOTE: // EPOffset if an offset to the EP value in PE header // it's NOT actual offset to the EP. it only points to the EP RVA in PE
// NOTE: // secRawOffset if raw offset where shell-code is placed
// A. save all important info to the shell, correct it inside
// find start of data store in shell body magicOffset = findMagicSequence((LPBYTE) ((DWORD) mem + secRawOffset), shellSize); if (magicOffset == 0) { printf("findMagicSequence failed!\n"; return 1; }
__asm { mov esi, mem add esi, EPOffset lodsd mov OEPRVA, eax // we've got OEP RVA here, needs 2 b translated } printf("OEPRVA = %d\n", OEPRVA);
ish = bpetGetSectionHeaderByRVA(mem, OEPRVA); if (ish == NULL) { printf("bpetGetSectionHeaderByRVA failed!\n"; return 2; }
// calculate distance between PEP and OEP distance = secVA - OEPRVA; printf("PEP OEP distance = %d\n", distance);
// convert RVA to raw offset OEPRO = bpetRVAToRawOffset(mem, OEPRVA); printf("OEPRO = %d\n", OEPRO);
// save OEP original code to the shell body __asm { cld mov esi, mem add esi, secRawOffset add esi, magicOffset // now esi points to the FF sequence add esi, MAGIC_LENGTH // skip it lodsd // size of the original code to save in eax push eax // save it for future use lodsd // offset to the orig store add esi, eax mov edi, mem add edi, OEPRO // get OEP code start xchg esi, edi pop ecx // get size of OEP original code to save
// swap EP code and shell's self-modifying code copy_ep_code: mov al, [esi] // get another byte to swap xchg al, [edi] xchg al, [esi] inc esi inc edi loop copy_ep_code // ecx decrements automatically
// now save some important info about target EP section mov edx, ish mov eax, [edx]ish.Misc.VirtualAddress stosd mov eax, [edx]ish.Misc.VirtualSize stosd mov eax, pass_hash stosd
// fix target EP code with proper values mov edi, mem add edi, OEPRO add edi, MAGIC_PEP_OEP_DISTANCE mov eax, distance stosd }
return 0; // it's all fine } extern "C" __declspec(dllexport) int restore(LPVOID mem, DWORD secRawOffset, DWORD shellSize, DWORD EPOffset) { DWORD magicOffset; DWORD OEPRO; // OEP raw offset in the file DWORD OEPRVA; // OEP RVA
// NOTE: // EPOffset if an offset to the EP value in PE header // it's NOT actual offset to the EP. it only points to the EP RVA in PE
// NOTE: // secRawOffset if raw offset where shell-code is placed
// find start of data store in shell body magicOffset = findMagicSequence((LPBYTE) ((DWORD) mem + secRawOffset), shellSize); if (magicOffset == 0) { printf("findMagicSequence failed!\n"; return 1; }
__asm { mov esi, mem add esi, EPOffset lodsd mov OEPRVA, eax // we've got OEP RVA here, needs 2 b translated } printf("OEPRVA = %d\n", OEPRVA);
// convert RVA to raw offset OEPRO = bpetRVAToRawOffset(mem, OEPRVA); printf("OEPRO = %d\n", OEPRO);
// save OEP original code to the shell body __asm { cld mov esi, mem add esi, secRawOffset add esi, magicOffset // now esi points to the FF sequence add esi, MAGIC_LENGTH // skip it lodsd // size of the original code to save in eax push eax // save it for future use lodsd // offset to the orig store add esi, eax mov edi, mem add edi, OEPRO // get OEP code start xchg esi, edi pop ecx // get size of OEP original code to save
// swap EP code and shell's self-modifying code copy_ep_code: mov al, [esi] // get another byte to swap xchg al, [edi] xchg al, [esi] inc esi inc edi loop copy_ep_code // ecx decrements automatically }
return 0; // it's all fine }
extern "C" __declspec(dllexport) void fail(char *msg) { printf("error:\n"; printf(msg); printf("\n"; getch(); exit(0); } extern "C" __declspec(dllexport) void clear_bound_import(LPVOID pe) { PIMAGE_NT_HEADERS inth; PIMAGE_DATA_DIRECTORY idt; BYTE bound_pos = IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
__asm { mov eax, pe add eax, [eax].e_lfanew mov inth, eax }
// kill bound! now! idt = &inth->OptionalHeader.DataDirectory[bound_pos]; if (idt != NULL) { printf("bound exists - "; if (idt->VirtualAddress != 0) printf("YES\n"; else printf("NO\n"; idt->VirtualAddress = 0; idt->Size = 0; } }
extern "C" __declspec(dllexport) void infect(char *target, char *shell, char *sec_name, char *password, char cure) { DWORD secVA = 0; // protector's EP DWORD secRawOffset = 0; DWORD EPOffset = 0; // raw offset to the OEP RVA HANDLE file; HANDLE map; LPVOID mem; PIMAGE_SECTION_HEADER ish;
printf("target = %s\n", target); if (!cure) { printf("shell = %s\n", shell); printf("password = %s\n", password); } printf("SecName = %s\n", sec_name);
if (!cure) { if (bpetAddSection(target, shell, sec_name, &secVA, NULL) != 0) fail("problems during injecting new section"; printf("new section VA = %d\n", secVA); }
file = CreateFile(target, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (file == INVALID_HANDLE_VALUE) fail("cant open file";
map = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 0, NULL); if (map == NULL) fail("cant create file mapping";
mem = MapViewOfFile(map, FILE_MAP_WRITE, 0, 0, 0); if (mem == NULL) fail("cant map view of file";
EPOffset = bpetGetEPFieldRawOffset((PBYTE) mem); if (EPOffset == 0) fail("cant get EP raw offset"; printf("EP offset = %d\n", EPOffset);
secRawOffset = bpetGetSectionRawOffset((PBYTE) mem, (PBYTE) sec_name); if (secRawOffset == 0) fail("cant get section raw offset"; printf("Section raw offset = %d\n", secRawOffset);
if (!cure) { // infect if (modify(mem, secRawOffset, GetFileSizeByName(shell), EPOffset, secVA, password) != 0) fail("modify failed!"; printf("modify - OK\n";
// won't erase all wrong sequences, like 0xFFFFFFFFFF if (encrypt((LPBYTE) ((DWORD) mem + secRawOffset), GetFileSizeByName(shell)) != 0) fail("encryption failed!"; printf("encrypt - OK\n";
clear_bound_import(mem); printf("clear_bound_import - OK\n"; } else { // restore ish = bpetGetSectionHeader(mem, sec_name); if (ish == NULL) fail("cant get protector's section header";
if (decrypt((LPBYTE) ((DWORD) mem + secRawOffset), ish->Misc.VirtualSize) != 0) fail("decrypt failed!"; printf("decrypt - OK\n";
if (restore(mem, secRawOffset, ish->Misc.VirtualSize, EPOffset) != 0) fail("restore failed!"; printf("restore - OK\n"; }
FlushViewOfFile(mem, 0); UnmapViewOfFile(mem); CloseHandle(map); CloseHandle(file);
if (cure) { if (bpetRemoveSectionByName(target, sec_name) != 0) fail("problems during removing section!";
printf("cure - OK\n"; } else { printf("inject - OK\n"; } } extern "C" __declspec(dllexport) void hash(char *in_name, char *out_name) { DWORD hash_code = 0; FILE *in, *out; char buf[1024]; DWORD cnt = 0; DWORD p;
if ((in = fopen(in_name, "rt") == NULL) { printf("cant open in file"; return; }
if (out_name == NULL) { lstrcpy(buf, in_name); lstrcat(buf, ".inc"; out_name = buf; }
if ((out = fopen(out_name, "wt") == NULL) { printf("cant open out file"; return; }
while (!feof(in)) { p = 0; do { // read til the CR or EOF buf[p++] = (char) fgetc(in); } while (buf[p - 1] != 10 && !feof(in)); buf[p - 1] = '\0';
if (lstrlen(buf) == 0) { // nuttin to hash fprintf(out, "\n"; continue; }
p = 0; // skip spaces while ((buf[p] == ' ' || buf[p] == '\t') && (buf[p] != '\0')) p++;
if (buf[p] == ';') { // is that comment? fprintf(out, "%s\n", buf); continue; }
if (buf[p] == 13 || buf[p] == 10) { // empty string? fprintf(out, "\n"; continue; }
hash_code = hash_string(buf); fprintf(out, "_%s dd 0x%0.8X\n", buf, hash_code); buf[0] = '\0'; cnt++; }
fclose(in); fclose(out); printf("functions hashed = %d\n", cnt); printf("hash - OK\n"; }
extern "C" __declspec(dllexport) DWORD get_size_by_header(PIMAGE_SECTION_HEADER ish, DWORD secCount) { DWORD hdrSize = 0;
while (secCount > 0) { secCount--; if (secCount == 0) hdrSize = ish->PointerToRawData + ish->SizeOfRawData; ish++; }
return hdrSize; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) { return 1; } //---------------------------------------------------------------------------
|
вот код BPET.h Код | #ifndef BPET_H #define BPET_H
// WARNING: // all function deal with a mapped exe file i.e. it should be in memory, but // sections should be aligned to file alignment. if you give // GetModuleHandle(NULL) here, functions like bpetGetSectionRawData won't // work. you should map file with your own hands. just map - nothing more.
// returns absolute address of the section's header in the memory PIMAGE_SECTION_HEADER bpetGetSectionHeader(LPVOID pe, char *sectionName);
// removes section with given name DWORD bpetRemoveSectionByName(char *, char *);
// converts RVA in a section to raw offset DWORD bpetRVAToRawOffset(LPVOID, DWORD);
// return section header by rva in that section PIMAGE_SECTION_HEADER bpetGetSectionHeaderByRVA(LPVOID, DWORD);
// returns offset of EP field DWORD bpetGetEPFieldRawOffset(PBYTE);
// returns offset of section start DWORD bpetGetSectionRawOffset(PBYTE, PBYTE);
// returns actual size of section, not aligned DWORD bpetGetSectionSize(PBYTE, PBYTE);
// returns copied bytes count DWORD bpetGetSectionRawData(PBYTE, PBYTE, PBYTE);
// copies template sfx.exe to output DWORD bpetPrepareSfxModule(char *, HANDLE);
// adds new section to dest (1st) with given name (3rd) DWORD bpetAddSection(char *, char *, char *, DWORD *, DWORD *);
#endif
|
Однако при попытке скомпилить это дело в BC++ вылетают 7 ошибок неких неразрешенных обьявлений в PEDll.obj=(Собственно помогите поправить.. Компилятор BC ++ 6.0 Это сообщение отредактировал(а) SGTeam - 24.8.2006, 10:08
|