информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Spanning Tree Protocol: недокументированное применениеЗа кого нас держат?Атака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Крупный взлом GoDaddy 
 Просроченный сертификат ломает... 
 Phrack #70/0x46 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[Pascal] CreateRemoteThread подводные камни. Что делать? Help, please ;-((( 26.10.02 23:06  Число просмотров: 773
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 26.10.02 23:16  Количество правок: 1
<"чистая" ссылка>
Ну вот, доигрался. Не хватает мне возможностей моего любимого компилера. Что делать? Ума не преложу. Неужели на Asm писать весь код?

Итак, проблема. Нужно кое-что поделать в адресном пространстве запущенного приложения — к примеру, RegEdit.
Вот код примера, а конкретные вопросы смотрите после ;-)
implementation
{$R *.DFM}
Type TBeepProc = Function(dwFreq, dwDuration: DWORD): BOOL; StdCall;

  Function rThread(aValue: Pointer): DWORD; StdCall;
  Begin
    TBeepProc(aValue)(5000, 10);
    Result := 777;

    ASM // Correct return throm tread
      POP EBP
      RET
    END;
  End;

procedure TForm1.Button1Click(Sender: TObject);

  Function GetProcessIDByTopmostWindowClass(aClass: String): DWORD;
  Var wHndl: THandle;
  begin
    wHndl := FindWindow(PChar(aClass), Nil);
    Win32Check(wHndl <> 0);
    GetWindowThreadProcessID(wHndl, @Result);
  End;

  Function GetProcAddrFromKernel(aProcName: String): Pointer;
  Var hMod: THandle;
  Begin
    hMod := GetModuleHandle(Kernel32);
    Win32Check(hMod <> 0);
    Result := GetProcAddress(hMod, PChar(aProcName));
    Win32Check(Result <> Nil);
  End;

Const pMemSize = 32;
Var
  pID, pHndl, tHndl, tID: THandle;
  rMem: Pointer;
  S: DWORD;
begin
  pID := GetProcessIDByTopmostWindowClass('RegEdit_RegEdit');
  Win32Check(pID <> 0);
  pHndl := OpenProcess(PROCESS_ALL_ACCESS, False, pID);
  Win32Check(pHndl <> 0);
  Try
    rMem := VirtualAllocEx(pHndl, Nil, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    Win32Check(rMem <> Nil);
    Try
      Win32Check(WriteProcessMemory(pHndl, rMem, @rThread, pMemSize, S));
      Win32Check(S = pMemSize);
      Win32Check(VirtualProtectEx(pHndl, rMem, pMemSize, PAGE_EXECUTE_READ, S));
      tHndl := CreateRemoteThread(pHndl, Nil, 0, rMem, GetProcAddrFromKernel('Beep'), CREATE_SUSPENDED, tID);
      Win32Check(tHndl <> 0);
      Try
        ResumeThread(tHndl);
        WaitForSingleObject(tHndl, INFINITE);
        Win32Check(GetExitCodeThread(tHndl, S));
        Caption := IntToStr(S);
      Finally
        CloseHandle(tHndl);
      End;
    Finally
      Win32Check(VirtualFreeEx(pHndl, rMem, 0, MEM_RELEASE) <> Nil);
    End;
  Finally
    CloseHandle(pHndl);
  End
end;

---

Итак, как можно видеть, открывается дескриптор процесса RegEdit. В нём выделяется память под поток. Копируется в эту память исполняемый код потока. Запускается поток на выполнение. Работает допущение, что базовый адрес, куда загружен Kernel32 в чужом процессе и в моём одинаковые.
Вопросы:
1) Существует ли более-менее "человеческий" способ определения размера исполняемого кода — или заходить в дебуггер и вручную его считать.
2) В этом простейшем случае инструкции в потоке идут одна за другой. Надо думать, что с появлением ветвлений, циклов и т.п., компилятор Delphi, "думая", что компилит для "родного" процесса, будет ставить абсолютные адреса переходов для ветвлений. Можно ли как-нибудь исхитриться и задать относительные? И вообще, возможно ли такое без применения in-line ассемблера?
3) Почему компилятор генерит такой код возврата из функции, помеченной как Stdcall: RET $0004. Я на всякий случай поставил просто RET. Как более правильно, поскольку что так, что эдак работает ;-)

И вообще, может я делаю что-то через задницу? ;-)) Что лучше всего использовать для создания кода, который будет исполняться в другом процессе?
Всем спасибо, жду ответов.
<programming> Поиск 








Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2021 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach