Здравствуйте! Вот пытаюсь разобраться с базонезависимым кодом в программах. Сразу возник вопрос, а где на его работу можно посмотреть в действии? И логично, я пошёл сразу, менять ImageBase свеже скомпилированного экзешника, и отладить код в ОЛЕДБГ. Но тут появилась куча фигни. Да, дельта смещение видно, но при вызове меседжбокса call не вызывает ф-цию, а прыгает на jmp который и прыгает в ф-цию, но адрес то(в jmp) не патченый! И как же cделать чтобы в call находился непосредственный адрес функции, без дополнительного поиска адреса? Например в исходниках МсиРема такое прокатывает! Кстати, можно ведь обойтись без дельты, путём вычисления смещения до переменных и суммирования текущего адреса с этим смещением?
в базонезависимом коде адреса АПИ-функций должны быть получены динамически, а не опираться на ИМПОРТ. PS: либо добавь к смещению джампа свою дельту и будет тебе счастье
А вот в исходниках МсРема это работает! Я бы срадостью добавил и к джампу, но его пишу не я а компилятор! А вычислять смещения до этого джампа это по-индусски! А как можно отловить инжект в отлаживаемый процесс? Ну.. представляю примеро, это если отлаживать два процесса паралельно Получить результат VirtualAllocEx, и уже искать этот адресс в отлаживаемом коде? А можно проще?
> Кстати, можно ведь обойтись без дельты получаешь EIP и складываешь с адресом, или что-то вроде такого (примерно такой код был в пакере от virogen): Код (Text): ; shellcode starts here call __start zeroday1 dd 12345678 zeroday2 dd 12345678 ;... zeroday1_addr = 4*0 zeroday2_addr = 4*1 ;... __start: pop ebp ; address of __start mov eax, ebp mov ecx, eax mov eax, [eax+zeroday1_addr] ; get zeroday1 value lea ecx, [eax+zeroday2_addr] ; get zeroday1 address
JacK3 Межсегментное ветвление(Call far), в юзермоде база сегмента кода нулевая, тоесть смещение в сегменте равно его адресу, а селектор 0x1B(KGDT_R3_CODE | RPL_MASK), но всёравно инструкция требует указатель на описатель ветвления(Sel:Offset), поэтому было решено использовать код: Код (Text): call Delta Delta: add dword ptr [esp],(offset Return - offset Delta) push BranchAddress ret Return:
jmp kernel32.GetModuleHandle ;это таблица импорта ... Call myexe.GetModuleHandle ;это вызов .... опкод кэла - 0xE8 0x00000000 ;дворд - это смещение на джамп относительно кэла опкод дальнего джампа - 0xE9 0x00000000 ;дворд - смещение функции относительно джампа можно поставить в твоем коде int3 Целевой процесс запустить на выполнение При инжекте олька остановится на твоем коде (точнее на int3)
А что мешает изменить базу образа в момент линковки? Причем на такую, которую загрузчик виндовс не выделит. Например на 0. Тогда загрузишься по нормальной базе и протестишь код.
если не ставить флаг relocation_stripped, то будет а еще можно поставить флаг dynamic_image_base - тогда тем более будет
Смещение переменных вычислять удобней с помощью макросов компилятора)) Так и буду делать! intel_x128 Ну это ясен! Приведу свой код и Рема. Мой: Код (Text): start: jmp next MsgBoxCaption db "Пум пурум",0 MsgBoxText db "Ало",0 next: call delta delta: pop ebx sub ebx,offset delta ;--------------------------------- push MB_OK lea esi, [EBX + offset MsgBoxCaption] push esi lea esi, [EBX + offset MsgBoxText] push esi push 0 lea eax, [ebx+MessageBox] call eax Как делает Рем: Код (Text): ;------------------ InjectCode: call $+5 pop esi sub esi, $-InjectCode-1 push 0 lea eax, [esi+caption-InjectCode] push eax lea eax, [esi+text-InjectCode] push eax push 0 call [esi+p_MessageBox-InjectCode] ;-------------------------------- p_MessageBox dd 0; выделил память под новый адрес ;-------------------------------- mov eax, [MessageBox] mov [p_MessageBox], eax;запомнил! MSoft А можешь подсказать с какими парамитрами можно линковать в МАСМ(32)?
Код (Text): Microsoft (R) Incremental Linker Version 5.12.8078 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. usage: LINK [options] [files] [@commandfile] options: /ALIGN:# /BASE:{address|@filename,key} /COMMENT:comment /DEBUG /DEBUGTYPE:{CV|COFF} /DEF:filename /DEFAULTLIB:library /DLL /DRIVER[:{UPONLY|WDM}] /ENTRY:symbol /EXETYPE:DYNAMIC /EXPORT:symbol /FIXED[:NO] /FORCE[:{MULTIPLE|UNRESOLVED}] /GPSIZE:# /HEAP:reserve[,commit] /IMPLIB:filename /INCLUDE:symbol /INCREMENTAL:{YES|NO} /LARGEADDRESSAWARE[:NO] /LIBPATH:dir /MACHINE:{ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4} /MAP[:filename] /MAPINFO:{EXPORTS|FIXUPS|LINES} /MERGE:from=to /NODEFAULTLIB[:library] /NOENTRY /NOLOGO /OPT:{ICF[,iterations]|NOICF|NOREF|NOWIN98|REF|WIN98} /ORDER:@filename /OUT:filename /PDB:{filename|NONE} /PDBTYPE:{CON[SOLIDATE]|SEPT[YPES]} /PROFILE /RELEASE /SECTION:name,[E][R][W][S][D][K][L][P][X] /STACK:reserve[,commit] /STUB:filename /SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]] /SWAPRUN:{CD|NET} /VERBOSE[:LIB] /VERSION:#[.#] /VXD /WARN[:warninglevel] /WINDOWSCE:{CONVERT|EMULATION} /WS:AGGRESSIVE выбирай нужное. А вообще, получать дельту совершенно не обязательно. Код можно тестить и в обычном приложении. Если ты вдруг неправильно получишь дельту или не так присвоишь адрес переменной, твоя программа просто упадет. Лично я не вижу совершенно никакой необходимости в том, чтобы загружать код не по своему адресу. Но если уж так сильно прям горит иметь дельту, отличную от 0, то просто выдели память через VirtualAlloc, скопируй туда базонезависимый код и сделай туда прыжок - эдакий эмулятор инжекта
жертва для отладок - ехе/длл из кучи нопов/инт3. в фасме/масме и лепится. или сразу ваш шелл в ехе слинкить.
JacK3 Собственно тема поднималась не раз - call через jmp в масм убирается альтернативным форматом API прототипов.