Сейчас на форуме: laslo, UniSoft, bartolomeo (+6 невидимых)

 eXeL@B —› Программирование —› Delphi, получить значение EAX
Посл.ответ Сообщение

Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 декабря 2011 21:22
· Личное сообщение · #1

В Olly ставлю бряк допустим по адресу 0045AB38 PUSH DWORD PTR DS:[EAX+60]
В дампе получаю значение лежащее в памяти по адресу EAX+60

Как программно можно узнать значение EAX если оно динамично и получить значение по EAX+60?

ReadProcessMemory(Handle, EAX+60, Buffer, SizeOf(Buffer), BytesRead);




Ранг: 392.8 (мудрец), 108thx
Активность: 0.260.01
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 02 декабря 2011 21:33
· Личное сообщение · #2

http://msdn.microsoft.com/en-us/library/windows/desktop/ms679362(v=VS.85).aspx

-----
StarForce и Themida ацтой!




Ранг: 37.1 (посетитель), 11thx
Активность: 0.030
Статус: Участник

Создано: 02 декабря 2011 21:34
· Личное сообщение · #3

Сначала нужно получить само значение регистра EAX. Код примерно следующий:
Code:
  1. hThread=OpenThread(THREAD_GET_CONTEXT, ...);
  2. thread_context.ContextFlags = CONTEXT_ALL;
  3. GetThreadContext(hThread,&thread_context);
  4. ReadProcessMemory(Handle, (void *)((char *)thread_context.Eax+60), Buffer, SizeOf(Buffer), BytesRead);




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 декабря 2011 22:51
· Личное сообщение · #4

Code:
  1. const
  2.   THREAD_ALL_ACCESS = 2032639;
  3.   CONTEXT_ALL = 524351;
  4. var
  5.   TreadContext: TContext;
  6.   ThreadRecord: TThreadEntry32;
  7.   BytesRead: DWord;
  8.   ThreadHandle: THandle;
  9.   Buffer : DWord;
  10. begin
  11.   ThreadHandle := OpenThread(THREAD_ALL_ACCESS, False, ThreadRecord.th32ThreadID);
  12.   TreadContext.ContextFlags := CONTEXT_ALL;
  13.   GetThreadContext(ThreadHandle, TreadContext);
  14.   ReadProcessMemory(ThreadHandle, PChar(TreadContext.EAX+60), @Buffer, SizeOf(Buffer), BytesRead);
  15.   ShowMessage(PChar(@Buffer));
  16.   CloseHandle(ThreadHandle);
  17. end;


Получилось так, но EAX в в чужой запущенной программе, как мне теперь подвязать это к чужой программе?




Ранг: 392.8 (мудрец), 108thx
Активность: 0.260.01
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 02 декабря 2011 23:08
· Личное сообщение · #5

Чет вопрос не понятен.

-----
StarForce и Themida ацтой!




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 декабря 2011 23:21
· Личное сообщение · #6

Чужая программа запущенна и работает, нужно написать код, чтобы изменить значение в её адресном пространстве, а чтобы найти адрес значения в памяти нужно брякнуть 0045AB38 PUSH DWORD PTR DS:[EAX+60] и по адресу EAX+60, будет значение, но EAX динамичен и адреса в памяти разные.



Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 02 декабря 2011 23:42
· Личное сообщение · #7

пишите свой мини-отладчик, который будет запускать прогу, ставить бряк, и после срабатывания бряка читать контекст

PE_Kill выкладывал где-то тут сырки своего отладчика (TDebugger вроде назывался)



Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 декабря 2011 23:51
· Личное сообщение · #8

Нет, я не пишу отладчик, мне нужно лишь прочитать значение в памяти по адресу, который постоянно меняется.




Ранг: 529.0 (!), 110thx
Активность: 0.290.04
Статус: Участник
5KRT

Создано: 03 декабря 2011 00:19
· Личное сообщение · #9

Terminate
Или отладчик или запись прыжка зацикленного на себя. Другого не дано. tihiy_grom верно сказал

-----
Research For Food




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 00:32
· Личное сообщение · #10

Ясно. Всем спасибо.



Ранг: 137.9 (ветеран), 45thx
Активность: 0.080
Статус: Участник

Создано: 03 декабря 2011 02:42
· Личное сообщение · #11

Terminate
я думаю не приват:

Code:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     eName: TEdit;
  12.     ePass: TEdit;
  13.     btnSniff: TButton;
  14.     btnClose: TButton;
  15.     lblLog: TLabel;
  16.     Button1: TButton;
  17.     procedure btnSniffClick(Sender: TObject);
  18.     procedure Button1Click(Sender: TObject);
  19.   private
  20.     { Private declarations }
  21.   public
  22.     { Public declarations }
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.   WantToClose: boolean = false;
  28.  
  29. const
  30.   LOOP: array [0..1] of Byte = ($EB,$FE);
  31.   addr = $0044D10F;
  32.   addr1 = $0040130a;
  33.  
  34. implementation
  35.  
  36. {$*.dfm}
  37.  
  38. function SniffSerial(PI: PROCESS_INFORMATION; Ctx: _Context): string;
  39. var
  40.   X: Cardinal;
  41.   Buff: PChar;
  42. begin
  43. // выделяем немного памяти
  44.   GetMem(Buff,50);
  45.  
  46. // останавливаем программу, чтобы получить контекст
  47.   SuspendThread(PI.hThread);
  48.   GetThreadContext(PI.hThread,Ctx);
  49.  
  50. // считываем [EAX] (правильный серийный номер)
  51.   ReadProcessMemory(PI.hProcess, Pointer(Ctx.Edx),Buff,50,X);
  52.  
  53. // устанавливаем результат и освобождаем буффер
  54.   Result:=Trim(Buff);
  55.   FreeMem(Buff);
  56. end;
  57.  
  58. procedure TForm1.btnSniffClick(Sender: TObject);
  59. var
  60.   PI: PROCESS_INFORMATION;
  61.   SI: STARTUPINFO;
  62.   Context: _CONTEXT;
  63.   Buffer: PChar;
  64.   ORIG: array [0..1] of Byte;
  65.   S: string;
  66.   W: DWORD;
  67. begin
  68.   // дисаблим кнопку (избегаем запуска цели несколько раз)
  69.   btnSniff.Enabled := False;
  70.   // выделяем паямть и инициализируем вары
  71.   GetMem(Buffer, 255);
  72.   FillChar(PI, SizeOf(TProcessInformation), #0);
  73.   FillChar(SI, SizeOf(TStartupInfo), #0);
  74.   SI.cb := SizeOf(SI);
  75.   //создаём процесс (засуспеженный)
  76.   if not CreateProcess('1.exe', nil, nil, nil, False, CREATE_SUSPENDED, nil, nil, SI, PI) then
  77.   begin
  78.     // активируем кнопку
  79.     btnSniff.Enabled := True;
  80.     // устанавливаем новый лог
  81.     lblLog.Caption := 'Failed to load process!';
  82.     Exit;
  83.   end;
  84.   // читаем оригинальные байты
  85.   ReadProcessMemory(PI.hProcess, Pointer(addr), @ORIG, 2, W);
  86.   // пишем непрерывный цикл
  87.   WriteProcessMemory(PI.hProcess, Pointer(addr), @LOOP, 2, W);
  88.   // восставнавливаем работу программы
  89.   ResumeThread(PI.hThread);
  90.   Context.ContextFlags := $00010000 + 15 + $10;
  91.   // устанавливаем новый лог
  92.   lblLog.Caption := 'Process patched!' + #13 + 'Now enter a name and press the "Check" button...';
  93.   while GetThreadContext(PI.hThread, Context) do
  94.   begin
  95.     // проверяем достигли ли мы цикла?
  96.     if Context.Eip = addr then
  97.     begin
  98.       // получаем серийный номер и кладём его в "S"
  99.       S := SniffSerial(PI, Context);
  100.       // восстанавливаем оригинальныйе байты и продолжаем работу программы
  101.       WriteProcessMemory(PI.hProcess, Pointer(addr), @ORIG, 2, W);
  102.       ResumeThread(PI.hThread);
  103.       // копируем серийный номер в буффер обмена и устанавливаем новый лог
  104.       ePass.Text := s;
  105.       lblLog.Caption := 'Your serial has been copied to clipboard!';
  106.     end;
  107.     // ждём 10 миллисекунд
  108.     Sleep(10);
  109.     Application.ProcessMessages;
  110.     // если пользователь хочет закрыть сниффер до выхода из программы, то закрываем и цель тоже
  111.     if WantToClose then
  112.     begin
  113.       TerminateThread(PI.hThread, 0);
  114.       Close;
  115.     end;
  116.   end;
  117.   // высвобождаем память выделенную в начале
  118.   FreeMem(Buffer);
  119.   // активируем кнопку
  120.   btnSniff.Enabled := True;
  121. end;
  122.  
  123. function SniffMain(ProcessName: string; Adress: Cardinal): string;
  124.  
  125.  function Sniff(PI: PROCESS_INFORMATION; Ctx: _Context): string;
  126. var
  127.   X: Cardinal;
  128.   Buff: PChar;
  129. begin
  130.   GetMem(Buff,50);
  131.   SuspendThread(PI.hThread);
  132.   GetThreadContext(PI.hThread,Ctx);
  133.   ReadProcessMemory(PI.hProcess, Pointer(Ctx.Edx),Buff,50,X);
  134.   Result:=Trim(Buff);
  135.   FreeMem(Buff);
  136. end;
  137.  
  138.  
  139.  
  140. function MemFind(ProcessHandle: Thandle; Addr: Cardinal; Value: array of byte; var RetAdr: Cardinal): boolean;
  141. var
  142.   Mbi: TMemoryBasicInformation;
  143.   Buf: PChar;
  144.   gif: Pchar;
  145.   I, J: Cardinal;
  146.   BytesRead: Dword;
  147.  
  148. begin
  149.  Result := false;
  150.   if ProcessHandle <> 0 then
  151.   try
  152.     J := 0;
  153.     RetAdr := 0;
  154.     Result := false;
  155.     while (VirtualQueryEx(ProcessHandle, Pointer(Addr), Mbi, SizeOf(Mbi)) <> 0) and (RetAdr = 0) do
  156.     begin
  157.  
  158.       if (Mbi.State = MEM_COMMIT) and not ((Mbi.Protect and PAGE_GUARD) = PAGE_GUARD) then
  159.       begin
  160.  
  161.         GetMem(Buf, Mbi.RegionSize);
  162.         try
  163.  
  164.           if ReadProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf,
  165.             Mbi.RegionSize, BytesRead) then
  166.           begin
  167.  
  168.             for I := 0 to BytesRead - SizeOf(Value) do
  169.             begin
  170.               if byte(Buf[I]) = (Value[J]) then
  171.               begin
  172.                 if J < SizeOf(Value) then
  173.                   Inc(j)
  174.                 else
  175.                 begin
  176.                   RetAdr := Cardinal(Mbi.BaseAddress) + I;
  177.                   Result := true;
  178.                 end;
  179.  
  180.  
  181.               end
  182.               else
  183.                 J := 0;
  184.             end;
  185.           end
  186.           else
  187.             MessageBox(0, Pchar('Failed to read process memory ' + IntToStr(GetLastError)), '', 0);
  188.  
  189.         finally
  190.           FreeMem(Buf);
  191.  
  192.         end;
  193.       end;
  194.  
  195.       Addr := Addr + Mbi.RegionSize;
  196.     end;
  197.  
  198.   finally
  199.  
  200.   end
  201.   else
  202.     MessageBox(0, Pchar('Failed to open process'), '', 0);
  203. end;
  204.  
  205.  
  206. var
  207.   PI: PROCESS_INFORMATION;
  208.   SI: STARTUPINFO;
  209.   Context: _CONTEXT;
  210.   Buffer: PChar;
  211.   ORIG: array [0..1] of Byte;
  212.   S: string;
  213.   W: DWORD;
  214.   adr2: Cardinal;
  215.  begin
  216.   GetMem(Buffer, 255);
  217.   FillChar(PI, SizeOf(TProcessInformation), #0);
  218.   FillChar(SI, SizeOf(TStartupInfo), #0);
  219.   SI.cb := SizeOf(SI);
  220.  
  221.   if not CreateProcess(pchar(ProcessName), nil, nil, nil, False, CREATE_SUSPENDED, nil, nil, SI, PI) then
  222.   begin
  223.     Exit;
  224.   end;
  225.   SuspendThread()
  226.  
  227.   ResumeThread(PI.hThread);
  228.   Context.ContextFlags := $00010000 + 15 + $10;
  229.  while GetThreadContext(PI.hThread, Context) do
  230.   begin
  231.     if Context.Eip = addr then
  232.     begin
  233.  
  234.       ResumeThread(PI.hThread);
  235.       Result := s;
  236.       Break;
  237.     end;
  238.     Sleep(10);
  239.     Application.ProcessMessages;
  240.   end;
  241.   CloseHandle(PI.hThread);
  242.   FreeMem(Buffer);
  243.  end;
  244.  
  245.  
  246.  
  247. procedure TForm1.Button1Click(Sender: TObject);
  248. begin
  249. SniffMain('1.exe', 0);
  250. end;
  251.  
  252. end.





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 05:42
· Личное сообщение · #12

yanus0 вся работа ведется с одним потоком, поэтому нужно смотреть основной ли поток мы хотим обрабатывать, иначе добавить функционал слежения за потоками.

>> function MemFind(ProcessHandle: Thandle; Addr: Cardinal; Value: array of byte; var RetAdr: Cardinal): boolean;
Очень опасно так писать. При таком подходе компилятор генерирует код, который копирует массив на стек и передает в качестве параметра весь массив на стеке, у меня были случаи переполнения стека из за этого. Лучше так:

function MemFind(ProcessHandle: Thandle; Addr: Cardinal; Value: PByteArray; var RetAdr: Cardinal): boolean;
***
if byte(Buf[I]) = (Value^[J]) then

-----
Yann Tiersen best and do not fuck




Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 03 декабря 2011 14:02
· Личное сообщение · #13

Terminate пишет:
Чужая программа запущенна и работает, нужно написать код, чтобы изменить значение в её адресном пространстве, а чтобы найти адрес значения в памяти нужно брякнуть 0045AB38 PUSH DWORD PTR DS:[EAX+60] и по адресу EAX+60, будет значение, но EAX динамичен и адреса в памяти разные.


а лодырь не канает ?



Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 15:41
· Личное сообщение · #14

yanus0 Спасибо за исходник.
Из всего кода достаточно procedure btnSniffClick и function SniffSerial, но это при использовании как лоадера, а вот как подключится к существующему процессу без CreateProcess и без Аттача, вот это вопрос.

Я так понимаю нужно получить ID главного треда, только пока неясно как.




Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

Создано: 03 декабря 2011 15:51
· Личное сообщение · #15

В большинстве случаев значение еах есть где-то в памяти. Найдете где и сможете получать свое значение в любой момент через обычное чтение памяти. Почитайте про создание трейнеров и динамические значения в памяти.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 03 декабря 2011 15:56
· Личное сообщение · #16

Terminate
Если используется аттач, то нужно делать, как в дебаггерах - DebugActiveProcess, перечислили все потоки в отлаживаемом приложении через те же Tool help, OpenThread для каждого потока, а на интересующее место CC (int3). Когда WaitForDebugEvent будет сигнализировать о срабатывании бряка, смотрим, наш ли бряк, GetThreadContext + ReadProcessMemory, декремент EIP, восстанавливаем затёртый байт, SetThreadContext, FlushInstructionCache, а в конце - DebugActiveProcessStop.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 16:06
· Личное сообщение · #17

Nightshade В данном случае, значение EAX постоянно изменяется и чтобы получить правильные данные, нужно после определённых действий читать EAX.



Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 16:14
· Личное сообщение · #18

ARCHANGEL В принципе, действия с отладкой я думаю тут и не потребуются, тут достаточно зациклить как в исходниках, только вот проблема с определением главного потока.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 03 декабря 2011 16:16 · Поправил: ARCHANGEL
· Личное сообщение · #19

Terminate
Да ну - всё гораздо проще. Если зациклили, то читайте контексты всех потоков и сравнивайте EIP с адресом, на котором зациклили. Если нашлось совпадение, то берёте из считанного контекста значение еах, читаете память, снимаете зацикливание и всё.

-----
Stuck to the plan, always think that we would stand up, never ran.





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 17:38
· Личное сообщение · #20

Terminate пишет:
В данном случае, значение EAX постоянно изменяется и чтобы получить правильные данные, нужно после определённых действий читать EAX.

Оно же не берется от балды, Nightshade всё правильно написал, только видимо ты не понимаешь сути, а реализовать пытаешься тупо по тому что в отладчике видел, в этом и проблема.

-----
Yann Tiersen best and do not fuck





Ранг: 392.8 (мудрец), 108thx
Активность: 0.260.01
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 03 декабря 2011 18:24
· Личное сообщение · #21

Terminate
>PE_Kill выкладывал где-то тут сырки своего отладчика (TDebugger вроде назывался)

Не парься, найди компонент и используй его, там все просто...

Компонента создаст тебе процесс, остановит в нужном месте, и отдаст значение EAX, и все

-----
StarForce и Themida ацтой!




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 18:36
· Личное сообщение · #22

Что-то я таких компонентов не встречал, по запросу TDebugger выдаёт ссылки на отладчик для php.



Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 19:58
· Личное сообщение · #23

На основе вышеизложенного исходника, получился код:
Code:
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   THREAD_ALL_ACCESS = 2032639;
  4.   CONTEXT_ALL = 524351;
  5.   LOOP: array [0..1] of Byte = ($EB,$FE);
  6. var
  7.   ORIG: array [0..1] of Byte;
  8.   s: string;
  9.   Buffer: PChar;
  10.   ProcessID, ThreadsID, Bytes: DWord;
  11.   ProcessHandle: THandle;
  12.   ThreadContext: TContext;
  13. begin
  14.   ProcessHandle := FindWindow(nil, 'Прога');
  15.   GetWindowThreadProcessId(ProcessHandle, @ProcessID);
  16.   ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID);
  17.   ThreadsID := CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD, ProcessID);
  18.   OpenThread(THREAD_ALL_ACCESS, False, ThreadsID);
  19.   ThreadContext.ContextFlags := CONTEXT_ALL;
  20.   SuspendThread(ThreadsID);
  21.   ReadProcessMemory(ProcessHandle, Pointer($0045AB38), @ORIG, 2, Bytes);
  22.   WriteProcessMemory(ProcessHandle, Pointer($0045AB38), @LOOP, 2, Bytes);
  23.   ResumeThread(ThreadsID);
  24.     while True do
  25.       begin
  26.         GetThreadContext(ThreadsID, ThreadContext);
  27.           if ThreadContext.EIP = $0081E9F4 then
  28.             begin
  29.               SuspendThread(ThreadsID);
  30.               GetThreadContext(ThreadsID, ThreadContext);
  31.               ReadProcessMemory(ProcessHandle, Pointer(ThreadContext.EAX), Buffer, 4, Bytes);
  32.               s := Trim(Buffer);
  33.               WriteProcessMemory(ProcessHandle, Pointer($0045AB38), @ORIG, 2, Bytes);
  34.               ResumeThread(ThreadsID);
  35.               ShowMessage(s);
  36.               Exit;
  37.             end;
  38.           Sleep(10);
  39.           Application.ProcessMessages;
  40.       end;
  41.   CloseHandle(ProcessHandle);
  42. end;

но он отрабатывает не правильно, программу он вроде зацикливает но EIP не находит.



Ранг: 137.9 (ветеран), 45thx
Активность: 0.080
Статус: Участник

Создано: 03 декабря 2011 20:34
· Личное сообщение · #24

Terminate
Под дебагером посмотри что происходит.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 03 декабря 2011 20:48
· Личное сообщение · #25

Terminate
Так вы ж хрень открываете:

Code:
  1.   ThreadsID := CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD, ProcessID);
  2.   OpenThread(THREAD_ALL_ACCESS, False, ThreadsID);


-----
Stuck to the plan, always think that we would stand up, never ran.





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 21:09
· Личное сообщение · #26

+1, снапшот открывает
Елы палы, апи же в мсдн описаны, как такую хуйню можно написать?

-----
Yann Tiersen best and do not fuck


| Сообщение посчитали полезным: SReg

Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 21:19 · Поправил: Terminate
· Личное сообщение · #27

Я подозревал, что в этом одна из проблем
Прочитал: "If the function succeeds, it returns an open handle to the specified snapshot." оказывается хендл снимка




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 03 декабря 2011 21:53
· Личное сообщение · #28

Terminate
Щас посмотрел ваш код дальше. О, господи! Святые небеса! Мало того, что снапшот открываете, так вы не используете результат OpenThread, вы потом хэндл снапшота используете как хэндл потока для чтения контекста!

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 5.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 декабря 2011 22:10
· Личное сообщение · #29

Code:
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   THREAD_ALL_ACCESS = 2032639;
  4.   CONTEXT_ALL = 524351;
  5.   LOOP: array [0..1] of Byte = ($EB,$FE);
  6. var
  7.   PI: PROCESS_INFORMATION;
  8.   ORIG: array [0..1] of Byte;
  9.   s: string;
  10.   Buffer: PChar;
  11.   ThreadEntry: TThreadEntry32;
  12.   SnapHandle, ProcessID, ThreadsID, Bytes: DWord;
  13.   ProcessHandle: THandle;
  14.   ThreadContext: TContext;
  15.   Find: Boolean;
  16. begin
  17.   ProcessHandle := FindWindow(nil, 'Прога');
  18.   GetWindowThreadProcessId(ProcessHandle, @ProcessID);
  19.   ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID);
  20.   SnapHandle := CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD, ProcessID);
  21.   ThreadEntry.dwSize := SizeOf(ThreadEntry);
  22.   Find := Thread32First(SnapHandle, ThreadEntry);
  23.     while Find do
  24.       begin
  25.         if ProcessID = ThreadEntry.th32OwnerProcessID then
  26.           begin
  27.             ThreadsID := ThreadEntry.th32ThreadID;
  28.             Break;
  29.           end;
  30.         Find := Thread32Next(SnapHandle, ThreadEntry);
  31.       end;
  32.   CloseHandle(SnapHandle);
  33.   OpenThread(THREAD_ALL_ACCESS, False, ThreadsID);
  34.   ThreadContext.ContextFlags := CONTEXT_ALL;
  35.   SuspendThread(ThreadsID);
  36.   ReadProcessMemory(ProcessHandle, Pointer($0081E9F4), @ORIG, 2, Bytes);
  37.   WriteProcessMemory(ProcessHandle, Pointer($0081E9F4), @LOOP, 2, Bytes);
  38.   ResumeThread(ThreadsID);
  39.     while True do
  40.       begin
  41.         GetThreadContext(ThreadsID, ThreadContext);
  42.           if ThreadContext.EIP = $0081E9F4 then
  43.             begin
  44.               SuspendThread(ThreadsID);
  45.               GetThreadContext(ThreadsID, ThreadContext);
  46.               ReadProcessMemory(ProcessHandle, Pointer(ThreadContext.EAX), Buffer, 4, Bytes);
  47.               s := Trim(Buffer);
  48.               WriteProcessMemory(ProcessHandle, Pointer($0081E9F4), @ORIG, 2, Bytes);
  49.               ResumeThread(ThreadsID);
  50.               ShowMessage(s);
  51.               Exit;
  52.             end;
  53.           Sleep(10);
  54.           Application.ProcessMessages;
  55.       end;
  56.   CloseHandle(ProcessHandle);
  57. end;

ARCHANGEL как использовать результат от OpenThread? в SuspendThread(?);
Результат от OpenThread почему-то равен хендлу снапшота.




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 03 декабря 2011 22:42
· Личное сообщение · #30

надо понимать, что пишешь, а не бездумно копировать

http://vsokovikov.narod.ru/New_MSDN_API/Process_thread/fn_openthread.htm

Code:
  1. hThread := OpenThread(THREAD_ALL_ACCESS, False, ThreadsID);
  2. SuspendThread(hThread);


-----
[nice coder and reverser]



 eXeL@B —› Программирование —› Delphi, получить значение EAX
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати