Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Внедрение кода в стороннее приложение, XP SP3, внедрение dll под XP, приложение падает 
:(
    Опции темы
Illusion Dolphin
Дата 24.12.2012, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Проблема только для XP, делается:
CreateProcess с флагом CREATE_SUSPENDED
CreateRemoteThread
WaitForSingleObject (созданный поток)
ResumeThread (оригинальный поток приложения).

Чтобы избежать проблем, всё "тёмное" дело делается не в DLL_PROCESS_ATTACH, а при вызове отдельной функции LoadHook, которая экспортируется из dll. 

Внедряемый код делает:
1) LoadLibraryW(DLL_PATH)
2) StartProc = GetProcAddress("LoadHook")
3) StartProc()
4) ExitThread(0)

В результате имеем что программа завершает работу :( Читал форумы, люди на это наталкиваются: 
http://stackoverflow.com/questions/9695370...-primary-thread
http://www.wasm.ru/forum/viewtopic.php?pid=308079 
http://www.gamedeception.net/threads/17964...s-what-the-fuck
http://bugtraq.ru/cgi-bin/forum.mcgi?type=...=6&m=143610
http://forum.sources.ru/index.php?showtopic=266627 тут тоже проблемы у людей

Кто-то пишет что в XP странный загрузчик и если запускать с CREATE_SUSPENDED, то exe ещё недоинициализирован, что исправили в поздних виндах. Тестируется на SP3, более ранние версии неинтересны как устаревшие.

Хотелось бы услышать Ваши идеи, заранее спасибо!

P.S. Это не вирус smile. В подписи - приложение, которое использует внедрение для того, чтобы "научить" сторонний видеоплеер читать зашифрованные видеофайлы. Всё даже работает, но есть неприятное ощущение что что-то неправильно.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Чучмек
Дата 24.12.2012, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



createprocess с флагом CREATE_SUSPENDED
выделение памяти в ап процесса - VirtualAllocEx /PAGE_EXECUTE_READWRITE
по адресу точки входа записывается jmp на выделенную память.
в выделенную память записывается загрузчик+имя dll+оригинальный код точки входа.
ResumeThread
Загрузчик загружает внедряемую dll, восстанавливает оригинальный код в точке входа, передает управление на точку входа

Добавлено @ 23:12
D7
Код

procedure load;
asm
mov ebp,esp
push $11111110  // virtualprotect ebp-4
push $11111111  // loadlibrary    ebp-8
push $11111112  // dll name       ebp-12
push $11111113  // old cod        ebp-16
push $11111114  // start adr      ebp-20
sub esp,4       // место под memflag

mov eax,ebp
sub eax,24
push eax      //oldflag
push $40      //PAGE_READWRITE
push 5        //size
push [ebp-20] //adr
call [ebp-4]  //virtualprotect

xor ecx,ecx
mov cl,5    //5 байт копировать
mov esi,[ebp-16] //сохраненный код
mov edi,[ebp-20] //точка входа
cld
rep movsb

mov eax,ebp
sub eax,24
push eax     //oldflag   //адрес для сохранения флага
push [eax]   //oldflag
push 5       //size
push [ebp-20]//adr
call [ebp-4] //virtualprotect
push [ebp-12] //dll name
call [ebp-8]//loadlibrary
mov esp,ebp

jmp  [ebp-20]//goto start   @b//
end;


var
  errorcode:byte;
function dll_inject(dll_name,exe_name,cmd_str:string):boolean;
type
 tmz=array[0..1]of char;
 tpe=array[0..3]of char;
 tjmprec=packed record
         jmpbyte:byte; // $E9
         jmpsize:integer;
         end;
var
h,fm,hdll:cardinal;
si:TStartupInfo;
pi:TProcessInformation;
ob:TOFStruct;
p,p1,mb,procmem:pointer;
entpoint:cardinal;
wb,rb,load_size:cardinal;
jmp_code:tjmprec;
begin
result:=false;
errorcode:=1;       //1-ошибка открытия исполняемого файла
h:=openfile(pchar(exe_name),ob,GENERIC_READ );
fm:=CreateFileMapping(h,nil,PAGE_READONLY ,0,getfilesize(h,nil),nil);
p:=MapViewOfFile(fm,FILE_MAP_READ,0,0,0);
if p=nil then exit;
inc(errorcode);    //2-файл не является исполняемым pe файлом
try
  try
    if tmz(PImageDosHeader(p)^.e_magic)<>'MZ' then exit;
    p1:=pointer(cardinal(p)+PImageDosHeader(p)^._lfanew);
    if tpe(PIMAGENTHEADERS(p1).Signature)='PE'#0#0 then exit;
    entpoint:=PIMAGENTHEADERS(p1).OptionalHeader.ImageBase+PIMAGENTHEADERS(p1).OptionalHeader.AddressOfEntryPoint;
    if (IMAGE_FILE_EXECUTABLE_IMAGE<>(IMAGE_FILE_EXECUTABLE_IMAGE and PIMAGENTHEADERS(p1).FileHeader.Characteristics))or
       (IMAGE_FILE_DLL=(IMAGE_FILE_DLL and PIMAGENTHEADERS(p1).FileHeader.Characteristics))
           then exit;
    if entpoint=0 then exit;
  except
    exit;
  end;
finally
 UnMapViewOfFile(p);
 CloseHandle(fm);
 CloseHandle(h);
end;
inc(errorcode);   //3 - ошибка при запуске exe
fillchar(si,sizeof(si),0);
si.cb:=sizeof(si);
if not createprocess(nil,pchar('"'+exe_name+'" '+cmd_str),nil,nil,true,CREATE_SUSPENDED,nil,nil,si,pi)then exit;
inc(errorcode);   //4 - ошибка при внедрении dll
load_size:=86;
wb:=load_size+length(dll_name)+sizeof(jmp_code)+1;
getmem(mb,wb);
try
 procmem:=VirtualAllocEx(pi.hProcess,nil,wb,MEM_COMMIT, PAGE_EXECUTE_READWRITE );
 if procmem=nil then exit;
 move((@load)^,mb^,load_size);
 hdll:=loadlibrary('kernel32.dll');
 pcardinal(cardinal(mb)+3)^:=cardinal(getprocaddress(hdll,'VirtualProtect')); // ebp
 pcardinal(cardinal(mb)+8)^:=cardinal(getprocaddress(hdll,'LoadLibraryA'));   // ebp-4
 pcardinal(cardinal(mb)+13)^:=cardinal(procmem)+load_size+sizeof(jmp_code);   // ebp-8
 pcardinal(cardinal(mb)+18)^:=cardinal(procmem)+load_size;                    // ebp-12
 pcardinal(cardinal(mb)+23)^:=entpoint;                                       // ebp-16
 rb:=sizeof(jmp_code);
 if not readprocessmemory(pi.hProcess,pointer(entpoint),pointer(cardinal(mb)+load_size),rb,rb)then exit;
 move( (@(dll_name[1]))^ ,(pointer(cardinal(mb)+load_size+sizeof(jmp_code)))^,length(dll_name)+1);
 pbyte(cardinal(mb)+wb-1)^:=0;
 if not writeprocessmemory(pi.hProcess,procmem,mb,wb,wb)then exit;
 jmp_code.jmpbyte:=$E9;
 jmp_code.jmpsize:=cardinal(procmem)-entpoint-sizeof(jmp_code);
 wb:=sizeof(jmp_code);
 if not writeprocessmemory(pi.hProcess,pointer(entpoint),@jmp_code,wb,wb)then exit;
finally
 freemem(mb);
 ResumeThread(pi.hThread);
 closehandle(pi.hThread);
 closehandle(pi.hProcess);
end;
errorcode:=0;
result:=true;
end;

Выложил код - заметил ошибку. Вложение заменил.

Это сообщение отредактировал(а) Чучмек - 25.12.2012, 02:15

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  Injector_dll.exe 408,50 Kb


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Illusion Dolphin
Дата 24.12.2012, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Упало :( 
См. аттач.

DLL пустая чтобы исключить возможные ошибки в коде, Project Manager на картинке не обновился ещё.

Это сообщение отредактировал(а) Illusion Dolphin - 24.12.2012, 23:29

Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  Issue_XP_Sp3.png 256,90 Kb


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Чучмек
Дата 24.12.2012, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



Да. Дествительно. На MediaPlayerClassic падает. Посмотрю в  чем бок. 


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Illusion Dolphin
Дата 24.12.2012, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Цитата

На MediaPlayerClassic падает. 

И ещё Windows Media Player, WinRar, Calc, freecell итд... Мне не удалось найти, что работает. 


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Чучмек
Дата 25.12.2012, 01:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



Была одна программа, которая вылетала при попытке внедрения.
Сегодня, на скорую руку исправил.
да вот не учел что delphi компилирует 
Код

push ebp-24
   
как
Код

push [ebp-24]

Совсем не так как ожидалось. (ожидалось, что вообще, так не скомпилируется.)
На радостях и "исправил". 

Сейчас исправил, вложение заменил.


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
northener
Дата 25.12.2012, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: нет
Всего: 20



Цитата(Чучмек @  25.12.2012,  01:13 Найти цитируемый пост)
ожидалось, что вообще, так не скомпилируется.

Почему ожидалось, что так не скомпилируется?
"Затолкать" в стек можно всё что угодно, включая "возраст бабушки водителя автобуса минус количество галош, имеющихся у этой бабушки умноженное на температуру окружаещего их воздуха в третью пятницу прошлого месяца! smile
Ибо суть интрукции PUSH - поместить в стек ещё одно целое число. И не важно что оно такое.


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
Чучмек
Дата 25.12.2012, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



Цитата(northener @  25.12.2012,  01:34 Найти цитируемый пост)
Ибо суть интрукции PUSH - поместить в стек ещё одно целое число. И не важно что оно такое.

Затолкать в стек значение регистра  это одна инструкция.
Затолкать в стек значение по адресу в регистре (+ смещение) это другая инструкция
а вот затолкать в стек значение регистра + константа - Существование такой инструкции маловероятно.
 



--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
northener
Дата 25.12.2012, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: нет
Всего: 20



Цитата(Чучмек @  25.12.2012,  01:54 Найти цитируемый пост)
а вот затолкать в стек значение регистра + константа - Существование такой инструкции маловероятно.

А почему бы и нет?



--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
northener
Дата 25.12.2012, 02:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: нет
Всего: 20



Цитата(northener @  25.12.2012,  02:13 Найти цитируемый пост)
А почему бы и нет?

Я это к тому, что в подобных случаях недостаточно "предполагать". Тут надо точно знать как какие инструкции компилятор встроенного ассемблера преобразует в машкод.


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
Illusion Dolphin
Дата 25.12.2012, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Финальный код у меня работает! Это уже хорошо smile Осталось этот ужас переписать нормально с юникодом, x64 и убрать ассемблемные вставки  smile 


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
bems
Дата 25.12.2012, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



в х64 нет абсолютного джампа
я юзал пару push-ret, если мне не изменяет склероз. и это больше пяти байт :(

Это сообщение отредактировал(а) bems - 25.12.2012, 15:18


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Чучмек
Дата 27.12.2012, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



Illusion Dolphin, как обстоят дела с x64? 
Цитата(Illusion Dolphin @  25.12.2012,  10:48 Найти цитируемый пост)
 и убрать ассемблемные вставки

Это не совсем вставка, это внедряемый загрузчик. Его можно заменить массивом-константой, но тогда нельзя будет его редактировать. 

32for32
Код

const
 LoaderSize=82; //размер загрузчика Loader определяется через вызов Loader+останов -> Ctrl+Alt+C ->F7 ->LoaderSize=[end]-[begin]

//{
procedure Loader; //Внедряемый загрузчик,для удобства, выполнен в виде ассемблерной процедуры.
asm
mov ebp,esp
push $11111110  // virtualprotect ebp-4
push $11111111  // loadlibrary    ebp-8
push $11111112  // dll name       ebp-12
push $11111113  // old cod        ebp-16
push $11111114  // start adr      ebp-20
sub esp,4       // место под memflag
lea eax,[ebp-24]
push eax      //oldflag
push $40      //PAGE_READWRITE
push 5        //size
push [ebp-20] //adr
call [ebp-4]  //virtualprotect
xor ecx,ecx
mov cl,5    //5 байт копировать
mov esi,[ebp-16] //сохраненный код
mov edi,[ebp-20] //точка входа
cld
rep movsb
lea eax,[ebp-24]
push eax     //oldflag   //адрес для сохранения флага
push [eax]   //oldflag
push 5       //size
push [ebp-20]//adr
call [ebp-4] //virtualprotect
push [ebp-12] //dll name
call [ebp-8]//loadlibrary
mov esp,ebp
jmp  [ebp-20]//goto start   @b//
end;
//}



// кому не нравится ассемблер - может принять на веру и взять загрузчик в виде массива-константы
//закомментировав  Loader и раскомментировав последующие строки
{//
type
 PLoadData=^TLoadData;
 TLoadData=array[0..LoaderSize-1]of byte;

const
 cLoader:TLoadData = (
  $89,$E5,$68,$10,$11,$11,$11,$68,
  $11,$11,$11,$11,$68,$12,$11,$11,
  $11,$68,$13,$11,$11,$11,$68,$14,
  $11,$11,$11,$83,$EC,$04,$8D,$45,
  $E8,$50,$6A,$40,$6A,$05,$FF,$75,
  $EC,$FF,$55,$FC,$31,$C9,$B1,$05,
  $8B,$75,$F0,$8B,$7D,$EC,$FC,$F3,
  $A4,$8D,$45,$E8,$50,$FF,$30,$6A,
  $05,$FF,$75,$EC,$FF,$55,$FC,$FF,
  $75,$F4,$FF,$55,$F8,$89,$EC,$FF,
  $65,$EC);
 //}


type
 PAdrRec=^TAdrRec;
 TAdrRec=packed record
  rb1:array [0..2]of byte;
  VirtualProtectAdr:pointer;
  rb2:byte;
  LoadLibraryAdr:pointer;
  rb3:byte;
  DllNameAdr:cardinal;
  rb4:byte;
  EPCodeAdr:cardinal;
  rb5:byte;
  EPAdr:cardinal;
 end;

 TJmp=packed record
  jb:byte;        //$E9
  jsize:cardinal;
 end;








function inject32(exe_name,dll_name:string):bool;
var
 h:cardinal;
 fm:cardinal;
 p,p1:pointer;
 entpoint:cardinal;
 si:TStartupInfo;
 pi:TProcessInformation;
 ob:TOFStruct;
 mem:pointer;
 memsize:cardinal;
 procmem:pointer;
{//                // раскомментировать если используем cLoader
 PLoad:PLoadData;
//}
 PAdr:PAdrRec;
 hdll:cardinal;
 bc:NativeUInt; //cardinal
 jmp:TJmp;
 //e:cardinal;
 //buff:array[0..255]of char;
const
 LoadLibraryName:array[1..2]of pchar =('LoadLibraryA','LoadLibraryW');
begin
result:=false;
fillchar(si,sizeof(si),0);
fillchar(pi,sizeof(pi),0);
h:=0;
fm:=0;
p:=nil;
mem:=nil;
try
 h:=CreateFile(pchar(exe_name),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
 fm:=CreateFileMapping(h,nil,PAGE_READONLY ,0,getfilesize(h,nil),nil);
 p:=MapViewOfFile(fm,FILE_MAP_READ,0,0,0);
 if p=nil  then exit;
 if PImageDosHeader(p)^.e_magic<>IMAGE_DOS_SIGNATURE then exit;
 p1:=pointer(cardinal(p)+PImageDosHeader(p)^._lfanew);
 if (PIMAGENTHEADERS(p1)^.Signature<>IMAGE_NT_SIGNATURE)or      //если файл не PE
    (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_I386)or //или если файл не Win32
    (PIMAGENTHEADERS(p1)^.OptionalHeader.Magic<>IMAGE_NT_OPTIONAL_HDR32_MAGIC)//или если заголовок OptionalHeader не PE32
     then exit;
 entpoint:=PIMAGENTHEADERS(p1).OptionalHeader.ImageBase+PIMAGENTHEADERS(p1).OptionalHeader.AddressOfEntryPoint;
 if (entpoint=0) or //если адрес точки входа нулевой
    (IMAGE_FILE_EXECUTABLE_IMAGE<>(IMAGE_FILE_EXECUTABLE_IMAGE and PIMAGENTHEADERS(p1).FileHeader.Characteristics))or //или если файл не исполняемый
    (IMAGE_FILE_DLL=(IMAGE_FILE_DLL and PIMAGENTHEADERS(p1).FileHeader.Characteristics))//или если файл dll
        then exit;
 si.cb:=sizeof(si);
 if not createprocess(nil,pchar(exe_name),nil,nil,true,CREATE_SUSPENDED,nil,nil,si,pi)then exit;
 memsize:=LoaderSize+sizeof(tjmp)+(length(dll_name)+1)*sizeof(dll_name[1]);
 getmem(mem,memsize);
 procmem:=VirtualAllocEx(pi.hProcess,nil,memsize,MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 if procmem=nil then exit;
 PAdr:=mem;
//{
 move((@loader)^,mem^,LoaderSize);  //закомментировать если используем сLoader
 //}
{//
 PLoad:=mem;    // раскомментировать если используем cLoader
 PLoad^:=cLoader;
//}
 hdll:=GetModuleHandle('kernel32.dll');
 PAdr^.VirtualProtectAdr:=GetProcAddress(hdll,'VirtualProtect');
 PAdr^.LoadLibraryAdr:=GetProcAddress(hdll,LoadLibraryName[sizeof(dll_name[1])]);
 PAdr^.DllNameAdr:=cardinal(procmem)+LoaderSize+sizeof(tjmp);
 PAdr^.EPCodeAdr:=cardinal(procmem)+LoaderSize;
 PAdr^.EPAdr:=entpoint;
 StrCopy(PChar(cardinal(mem)+LoaderSize+sizeof(tjmp)),PChar(dll_name));
 jmp.jb:=$E9;
 jmp.jsize:=cardinal(procmem)-entpoint-sizeof(tjmp);
 if not ReadProcessMemory(pi.hProcess,pointer(entpoint),pointer(cardinal(mem)+LoaderSize),sizeof(tjmp),bc) or
    not WriteProcessMemory(pi.hProcess,pointer(entpoint),@jmp,sizeof(TJmp),bc) or
    not WriteProcessMemory(pi.hProcess,procmem,mem,memsize,bc)  then
  begin
  //e:=GetLastError;
  //FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,e,0,@buff,sizeof(buff),0);
  //MessageBox(0,@buff,pchar('Error:'+inttostr(e)),0);
  TerminateProcess(pi.hProcess,0);
  exit;
  end;
 ResumeThread(pi.hThread);
finally
 FreeMem(mem);
 CloseHandle(pi.hProcess);
 CloseHandle(pi.hThread);
 UnMapViewOfFile(p);
 CloseHandle(fm);
 CloseHandle(h)
end;

result:=true;
end;


64for64
Код

const
 LoaderSize=152; //размер загрузчика Loader определяется через вызов Loader+останов -> Ctrl+Alt+C ->F7 ->LoaderSize=[end]-[begin]
//{
procedure Loader; //Внедряемый загрузчик,для удобства, выполнен в виде ассемблерной процедуры.
asm
push rbp
mov rax, $0000000000000001 // virtualprotect rbp+$48
push rax
mov rax, $0000000000000002 // loadlibrary    rbp+$40
push rax
mov rax, $0000000000000003 // dll name       rbp+$38
push rax
mov rax, $0000000000000004 // EP data        rbp+$30
push rax
mov rax, $0000000000000005 // EP adr         rbp+$28
push rax
sub rsp,$28           // переменная сохранения флага памяти  rbp+$20    +32байта резерв
mov rbp,rsp

mov rcx,[rbp+$28]       //Адрес точки входа
mov rdx,12              //12 байт
mov r8,PAGE_READWRITE   //новый флаг памяти
lea r9,[rbp+$20]        //куда сохранять старый флаг
call [rbp+$48]          //virtualprotect

xor rcx,rcx
mov cl,12               //копировать 12 байт
mov rsi,[rbp+$30]       //источник - оригинальные данные
mov rdi,[rbp+$28]       //приемник - точка входа
cld                     //направление ВПЕРЕД
rep movsb               //копировать

mov rcx,[rbp+$38]       //адрес с именем dll
call [rbp+$40]          //loadlibrary

mov rcx,[rbp+$28]       //Адрес точки входа
mov rdx,12              //12 байт
lea r9,[rbp+$20]        //куда сохранять флаг памяти
mov r8,[r9]             //востанавливаем старый флаг
call [rbp+$48]          //virtualprotect

mov rax,[rbp+$28]       //адреc точки входа
lea rsp,[rbp+$50]       //востанавливаем стек
pop rbp                 //востаавливаем rbp
push rax                //в стек адрес точки входа
ret                     //возвращаемся на точку входа
end;
//}


// кому не нравится ассемблер - может принять на веру и взять загрузчик в виде массива-константы
//закоментировав  Loader и раскоментировав последующие строки
{//
type
 PLoadData=^TLoadData;
 TLoadData=array[0..LoaderSize-1]of byte;

const
 cLoader:TLoadData=(
  $55,$48,$B8,$01,$00,$00,$00,$00,
  $00,$00,$00,$50,$48,$B8,$02,$00,
  $00,$00,$00,$00,$00,$00,$50,$48,
  $B8,$03,$00,$00,$00,$00,$00,$00,
  $00,$50,$48,$B8,$04,$00,$00,$00,
  $00,$00,$00,$00,$50,$48,$B8,$05,
  $00,$00,$00,$00,$00,$00,$00,$50,
  $48,$83,$EC,$28,$48,$89,$E5,$48,
  $8B,$4D,$28,$48,$BA,$0C,$00,$00,
  $00,$00,$00,$00,$00,$49,$B8,$04,
  $00,$00,$00,$00,$00,$00,$00,$4C,
  $8D,$4D,$20,$FF,$55,$48,$48,$31,
  $C9,$B1,$0C,$48,$8B,$75,$30,$48,
  $8B,$7D,$28,$FC,$F3,$A4,$48,$8B,
  $4D,$38,$FF,$55,$40,$48,$8B,$4D,
  $28,$48,$BA,$0C,$00,$00,$00,$00,
  $00,$00,$00,$4C,$8D,$4D,$20,$4D,
  $8B,$01,$FF,$55,$48,$48,$8B,$45,
  $28,$48,$8D,$65,$50,$5D,$50,$C3);
//}

type
PAdrRec=^TAdrRec;
TAdrRec=packed record
  rb1:array[0..2]of byte;
  VirtualProtectAdr:pointer;
  rb2:array[0..2]of byte;
  LoadLibraryAdr:pointer;
  rb3:array[0..2]of byte;
  DllNameAdr:NativeUInt;
  rb4:array[0..2]of byte;
  EPCodeAdr:NativeUInt;
  rb5:array[0..2]of byte;
  EPAdr:NativeUInt;
 end;

TJmp=packed record
 movrax:word;  //$B848
 adr:pointer;
 pushrax:byte; //$50
 ret:byte;     //$c3
 end;




function inject64(exe_name,dll_name:string):bool;
var
 h:THandle;
 fm:THandle;
 p,p1:pointer;
 entpoint:NativeUInt;
 si:TStartupInfo;
 pi:TProcessInformation;
 ob:TOFStruct;
 mem:pointer;
 memsize:NativeUInt;
 procmem:pointer;
{//                // раскоментировать если используем cLoader
 PLoad:PLoadData;
//}
 PAdr:PAdrRec;
 hdll:THandle;
 bc:NativeUInt;
 jmp:TJmp;
 //e:cardinal;
 //buff:array[0..255]of char;
begin
result:=false;
fillchar(si,sizeof(si),0);
fillchar(pi,sizeof(pi),0);
h:=0;
fm:=0;
p:=nil;
mem:=nil;
try
 h:=CreateFile(pchar(exe_name),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
 fm:=CreateFileMapping(h,nil,PAGE_READONLY ,0,getfilesize(h,nil),nil);
 p:=MapViewOfFile(fm,FILE_MAP_READ,0,0,0);
 if p=nil  then exit;
 if PImageDosHeader(p)^.e_magic<>IMAGE_DOS_SIGNATURE then exit;
 p1:=pointer(NativeUInt(p)+PImageDosHeader(p)^._lfanew);
 if (PIMAGENTHEADERS(p1)^.Signature<>IMAGE_NT_SIGNATURE)or      //если файл не PE
    (// (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_IA64) and  // ??? на IA64 файлах не проверял
      (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_AMD64) )or //или если файл не Win64
    (PIMAGENTHEADERS(p1)^.OptionalHeader.Magic<>IMAGE_NT_OPTIONAL_HDR64_MAGIC)//или если заголовок OptionalHeader не PE64
     then exit;
 entpoint:=PIMAGENTHEADERS(p1).OptionalHeader.ImageBase+PIMAGENTHEADERS(p1).OptionalHeader.AddressOfEntryPoint;
 if (entpoint=0) or //если адрес точки входа нулевой
    (IMAGE_FILE_EXECUTABLE_IMAGE<>(IMAGE_FILE_EXECUTABLE_IMAGE and PIMAGENTHEADERS(p1).FileHeader.Characteristics))or //или если файл не исполняемый
    (IMAGE_FILE_DLL=(IMAGE_FILE_DLL and PIMAGENTHEADERS(p1).FileHeader.Characteristics))//или если файл dll
        then exit;
 si.cb:=sizeof(si);
 if not createprocess(nil,pchar(exe_name),nil,nil,true,CREATE_SUSPENDED,nil,nil,si,pi)then exit;
 memsize:=LoaderSize+sizeof(tjmp)+(length(dll_name)+1)*2;
 getmem(mem,memsize);
 procmem:=VirtualAllocEx(pi.hProcess,nil,memsize,MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 if procmem=nil then exit;
 PAdr:=mem;
//{
 move((@loader)^,mem^,LoaderSize);  //закоментировать если используем сLoader
 //}
{//
 PLoad:=mem;    // раскоментировать если используем cLoader
 PLoad^:=cLoader;
//}
 hdll:=GetModuleHandle('kernel32.dll');
 PAdr^.VirtualProtectAdr:=GetProcAddress(hdll,'VirtualProtect');
 PAdr^.LoadLibraryAdr:=GetProcAddress(hdll,'LoadLibraryW');
 PAdr^.DllNameAdr:=NativeUInt(procmem)+LoaderSize+sizeof(tjmp);
 PAdr^.EPCodeAdr:=NativeUInt(procmem)+LoaderSize;
 PAdr^.EPAdr:=entpoint;
 StrCopy(PChar(NativeUInt(mem)+LoaderSize+sizeof(tjmp)),PChar(dll_name));
 jmp.movrax:=$B848;
 jmp.adr:=procmem;
 jmp.pushrax:=$50;
 jmp.ret:=$C3;
 if not ReadProcessMemory(pi.hProcess,pointer(entpoint),pointer(NativeUInt(mem)+LoaderSize),sizeof(tjmp),bc) or
    not WriteProcessMemory(pi.hProcess,pointer(entpoint),@jmp,sizeof(TJmp),bc) or
    not WriteProcessMemory(pi.hProcess,procmem,mem,memsize,bc)  then
  begin
  //e:=GetLastError;
  //FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,e,0,@buff,sizeof(buff),0);
  //MessageBox(0,@buff,pchar('Error:'+inttostr(e)),0);
  TerminateProcess(pi.hProcess,0);
  exit;
  end;
 ResumeThread(pi.hThread);
finally
 FreeMem(mem);
 CloseHandle(pi.hProcess);
 CloseHandle(pi.hThread);
 UnMapViewOfFile(p);
 CloseHandle(fm);
 CloseHandle(h)
end;

result:=true;
end;





--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Чучмек
Дата 27.12.2012, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 7
Всего: 41



64 битную версию не проверял на файлах IMAGE_FILE_MACHINE_IA64. Все файлы IMAGE_FILE_MACHINE_AMD64 . Хотя в описании PE
Цитата

только два значения считаются корректными в PE-файле IMAGE_FILE_MACHINE_IA64 и IMAGE_FILE_MACHINE_I386.

Наверно описание древнее, а для IMAGE_FILE_MACHINE_IA64 нужен другой загрузчик.
Еще встречал файлы с FileHeader.Machine=IMAGE_FILE_MACHINE_I386 и OptionalHeader.Magic=IMAGE_NT_OPTIONAL_HDR64_MAGIC
Как с ними быть? Не знаю.
В Win7 не для всех exe (для стандартных виндосовских файлов, например) доступны Read(Write)ProcessMemory.
Как запросить повышение прав?


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
bems
Дата 27.12.2012, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



дельфи не компилит под ia64, так что тут как не крутись


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1305 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.