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

 eXeL@B —› Программирование —› Loader + WriteProcessMemory в Windows7 x64
. 1 . 2 . >>
Посл.ответ Сообщение

Ранг: 7.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 февраля 2011 17:44 · Поправил: Sumeru
· Личное сообщение · #1

Привет всем, помогите, пожалуйста:

Нужно выполнить стандартную процедуру:
1. Запустить ехе файл и подменить пару байт в нем
За основу был взят код:
Code:
  1. program loader;
  2. uses
  3. Windows, Messages;
  4. {$R Loader.RES}
  5. var
  6.  si : Startupinfo;
  7.  pi : Process_Information;
  8.  NewData : array[0..1] of byte = ($90,$90);
  9.  NewDataSize : DWORD;
  10.  Bytesread : DWORD;
  11.  Olddata : array[0..1] of byte;
  12. Begin
  13.  ZeroMemory(@si,sizeof(si));
  14.  ZeroMemory(@pi,sizeof(pi));
  15.  FillChar(Si,Sizeof(si),0);
  16.  Si.cb:=Sizeof(si);
  17.  
  18.  NewDataSize := sizeof(newdata);
  19.  IF CreateProcess(nil,'Example.exe',nil,nil,FALSE,Create_Suspended,nil,nil  ,si,pi) = true then
  20.   begin
  21.    ReadProcessMemory(pi.hprocess,Pointer($403CEA),@olddata,2,bytesread);
  22.  if (olddata[0] = $75) and (olddata[1] = $19) then
  23.   begin
  24.    WriteProcessMemory(pi.hProcess, Pointer($403CEA), @NewData, NewDataSize, bytesread);
  25.    ResumeThread(pi.hThread);
  26.    CloseHandle(pi.hProcess);
  27.    CloseHandle(PI.hThread);
  28.   end else
  29.   begin
  30.    Messagebox(0,pchar('Bytes not found! Wrong version?...'),pchar('Error'),mb_iconinformation);
  31.    TerminateProcess(PI.hProcess,0);
  32.    CloseHandle(PI.hProcess);
  33.    CloseHandle(PI.hThread);
  34.   end;
  35. end;
  36. end.


Под х32 все замечательно работает, под х64 процесс стартует, но замены не происходит.
При этом VirtualProtect возвращает под х32 STATUS_OK, а под х64 - 0
А вот чтение/запись - ошибка.



Ранг: 617.3 (!), 677thx
Активность: 0.540
Статус: Участник

Создано: 27 февраля 2011 17:59
· Личное сообщение · #2

Попробуй перед WriteProcessMemory выполнить
VirtualProtectEx (pi.hProcess, Pointer($403CEA),NewDataSize,PAGE_EXECUTE_READWRITE,bytesread)
хотя х.з на 64 это сработает или нет!?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 27 февраля 2011 18:16
· Личное сообщение · #3

Кодес коряв тем, что не меняет атрибуты памяти+не учитывает, что база может измениться. Возможно, дело в одном из этого. Возможно, в другом, бери да смотри коды ошибок натив-функций.

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

Ранг: 7.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 февраля 2011 18:22 · Поправил: Sumeru
· Личное сообщение · #4

Спасибо, попробовал:

//нужно записать байты в область в 4кб, начиная от начала секции кода
Status:=Windows.VirtualProtectEx(pi.hProcess,@00401000,$1000,PAGE_EXEC UTE_READWRITE,@SavedFlags);

На выходе статус = True.
Сам лоадер и процесс, запускаемый из-под него - 32 битные

ReadProcess не работает...
Может размеры указателей надо не DWORD , а больше?

Сейчас проверю в отладчике



Ранг: 7.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 февраля 2011 18:45 · Поправил: Sumeru
· Личное сообщение · #5

При старте в отладчике:
ошибка вызова ntdll.NtProtectVirtualMemory = 0xC0000018 (STATUS_CONFLICTING_ADDRESSES)
Дохожу сюда:

Code:
  1. ntdll:7708FFC8 ntdll_NtProtectVirtualMemory:   
  2. ntdll:7708FFC8                                 
  3. ntdll:7708FFC8                                 
  4. ntdll:7708FFC8 mov     eax, 4Dh                
  5. ntdll:7708FFCD xor     ecx, ecx                
  6. ntdll:7708FFCF lea     edx, [esp+4]            
  7. ntdll:7708FFD3 call    large dword ptr fs:0C0h ;//здесь уже возвращается статус
  8. ntdll:7708FFDA add     esp, 4                  
  9. ntdll:7708FFDD retn    14h



Кстати, ни Yoda лоадер, ни DuP тоже стартуют процесс нормально, но не могут поменять байтики в процессе, ибо чтение байт по офсету нужному ничего не дает...



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 27 февраля 2011 20:07 · Поправил: ELF_7719116
· Личное сообщение · #6

Во-первых, ImageBase explora обычно равен 1000000. Во-вторых, читать\писать из 32 битн в 64 разве можно?? По факту это две разные архитектуры




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 27 февраля 2011 20:12
· Личное сообщение · #7

'Example.exe'
Сам лоадер и процесс, запускаемый из-под него - 32 битные
Ты читал топик то?



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 27 февраля 2011 20:32
· Личное сообщение · #8

Archer
Привычка все быстро читать(даже с ошибками)!
А по поводу почему ReadProcMem не работает-можно GetLastError попробовать поставить. Лоадер же из под учетки админа стартует?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 27 февраля 2011 20:50
· Личное сообщение · #9

Он сам стартует дочерний процесс, для этого не нужен админ, чтобы писать/читать в/из него.



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 27 февраля 2011 23:00
· Личное сообщение · #10

ну это само собой. Дело в том что когда я разбирал вопрос почему в висте 32 (насчет 7 не знаю) taskman без админ прав видит больше процессов чем PeTools, оказалось, что на висте в OpenProcess совсем другая маска по доступу идет. Подумал что может связано как-то(косвенно).
Одним словом, пока сам не посмотриш, сложно сказать что-то определеное.



Ранг: 7.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 февраля 2011 23:14 · Поправил: Sumeru
· Личное сообщение · #11

Loader стартую в контексте админских прав.

Пробовал читать по 1 байту, по килобайту....
Попробую перебрать параметры VirtualProtectEx

GetLastError = 0x000001E7 (Attempt to access invalid address.) = ERROR_INVALID_ADDRESS 487



Ранг: 60.6 (постоянный), 87thx
Активность: 0.060
Статус: Участник

Создано: 28 февраля 2011 00:18 · Поправил: Kaimi
· Личное сообщение · #12

Loader стартую в контексте админских прав.

Пробовал читать по 1 байту, по килобайту....
Попробую перебрать параметры VirtualProtectEx

GetLastError = 0x000001E7 (Attempt to access invalid address.) = ERROR_INVALID_ADDRESS 487

Ну покажи ещё раз код, может ты до сих пор не учитываешь что-то из перечисленного Арчером



Ранг: 7.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 28 февраля 2011 01:37 · Поправил: Sumeru
· Личное сообщение · #13

Похоже, нашел проблему...
при старте процесса под х32,
VirtualProtectEx(pi.hProcess,@00401000,$1000,....
адресация памяти в загружаемом процессе начинается как и при простом старте , от 401000..
А под х64 , процесс, несмотря на начало секции кода с 401000, смещен на 0x980000, т.е. адреса, которые надо читать и маппить будуь x+0x980000 (секция кода начинается с 0x401000+0x980000).
Отсюда и ошибки в протекте и, соответственно в чтении.

Вопрос только, как программно из лоадера узнать это смещение.
При каждом старте из лоадера, Image Base смещен на определенное значение, каждый раз разное.
Как узнать, с какого адреса загружен ехе?

GetModuleHandle возвращает родной ImageBase.




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

Создано: 28 февраля 2011 05:49
· Личное сообщение · #14

Sumeru как GetModuleHandle может вернуть тебе родной ImageBase, если эта апи работает с текущими модулями а ты работаешь с чужим процессом?

Тебе нужны --> апи перечисления процессов <-- ну или накрайняк через ReadProcessMemory пройдись по страничкам и найди страницу с PE Header'ом твоего подопытного exe

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





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 28 февраля 2011 09:27
· Личное сообщение · #15

Это релоцирование не привязано к х64, а будет работать на всех ОС>=висты, в том числе и на х86 тоже. И если бы ты читал посты выше, меньше бы было проблем, об этом косяке в кодесе я написал во 2 посте.



Ранг: 60.6 (постоянный), 87thx
Активность: 0.060
Статус: Участник

Создано: 28 февраля 2011 11:46
· Личное сообщение · #16

Sumeru пишет:
Как узнать, с какого адреса загружен ехе?

Воспользуйся NtQueryInformationProcess, прочитай пеб процесса, в нём содержится ImageBase по которому процесс загрузился




Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 28 февраля 2011 16:36 · Поправил: ajax
· Личное сообщение · #17

PE_Kill пишет:
накрайняк через ReadProcessMemory пройдись по страничкам и найди страницу с PE Header'ом твоего подопытного exe

Намного умнее, чем париться с перечислением всего по TlH/NtQ/ZqQ/Ps... Но есть вариант проще (при условии, что секция кода первая):
getthreadcontext(...,context)
code_base=context. - OEP

-----
От многой мудрости много скорби, и умножающий знание умножает печаль





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

Создано: 28 февраля 2011 17:35
· Личное сообщение · #18

В suspend режиме eip не будет равно oep, eip будет в недрах kernel или ntdll

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





Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 28 февраля 2011 18:12
· Личное сообщение · #19

PE_Kill
А кто-то разве сказал про EIP ? Спецом смайлик поставил, что кому надо, тот найдет. Фишка еще с доса, кажись.

-----
От многой мудрости много скорби, и умножающий знание умножает печаль




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 28 февраля 2011 23:05 · Поправил: Clerk
· Личное сообщение · #20

> Как узнать, с какого адреса загружен ехе?
RtlPcToFileHeader(), LdrFindEntryForAddress().

> code_base=context.
В произвольный момент времени в контексте потока данной инфы нет. Она там есть пока поток не начал исполняться вновь созданный.

> getthreadcontext(...,context)
ThreadQuerySetWin32StartAddress.

> ERROR_INVALID_ADDRESS
Причины:
STATUS_NOT_MAPPED_VIEW
STATUS_NOT_MAPPED_DATA
STATUS_NOT_COMMITTED
STATUS_UNABLE_TO_DECOMMIT_VM
STATUS_FREE_VM_NOT_AT_BASE
STATUS_MEMORY_NOT_ALLOCATED



Ранг: 145.8 (ветеран), 191thx
Активность: 0.140.36
Статус: Участник

Создано: 01 марта 2011 05:17 · Поправил: Alchemistry
· Личное сообщение · #21

Clerk пишет:
LdrFindEntryForAddress


Ахтунг. Мало того что она недокументированная так по функционалу все что она делает это смотрит первый модуль из Peb->Ldr->InLoadOrderModuleList.

Clerk пишет:
RtlPcToFileHeader


Дабл ахтунг.

Весь ее пэйлоад это вызов в локе
NtHeaders = RtlImageNtHeader(Base); где Base опять же из того же Peb->Ldr->InLoadOrderModuleList

Вот скажи мне какой смысл городить вот это недокументированное болото в обычной программе?


Есть официальный - документированный и рабочий метод.
psapi.dll -> EnumProcessModules/GetModuleInformation.

По смыслу оно сделает тоже самое что ты тут предложил - НО - у этого не будет никаких проблем с совместимостью. Чувствую вопли типа "какая есчо несовместимость эта системные функи".
Системным функам место в ntdll.dll и в натив приложениях в нормальных программах в импорте их быть не должно.




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

Создано: 01 марта 2011 07:40
· Личное сообщение · #22

Че то клерка опять понесло. Уже определили что образ мапится не на свою базу, нафига перечислять причины ERROR_INVALID_ADDRESS да еще и хардкод предлагать для безобидного лодыря.

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




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

Создано: 01 марта 2011 08:05
· Личное сообщение · #23

А что мешает сделать так:
CreateProcess(fpath, 0,0,0,0,DEBUG_PROCESS, 0,0, &sinfo, &pinfo)
while(1){
switch (de.dwDebugEventCode){
case CREATE_PROCESS_DEBUG_EVENT:
imagebase = (ULONG_PTR)de.u.CreateProcessInfo.lpBaseOfImage;

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


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

Создано: 01 марта 2011 08:13
· Личное сообщение · #24

Это довольно хреновое решение для лодыря, т.к. нужно будет висеть над жертвой до ее завершения, прятаться от обнаружения антидебаг трюками (для криптора так еще и драйвер нужно будет делать по хорошему) да и юзать дебагер для патча пары байт это ахтунг.

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




Ранг: 617.3 (!), 677thx
Активность: 0.540
Статус: Участник

Создано: 01 марта 2011 08:29
· Личное сообщение · #25

При создании процесса с опцией suspend загруженная ImageBase будет в EBX.




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

Создано: 01 марта 2011 08:33
· Личное сообщение · #26

Это не догма. Для вирусов еще пойдет, для всего остального нет. Знаю случаи когда в регистрах мусор а адрес на стеке (на EP) ведет вовсе не в kernel или ntdll.

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




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

Создано: 01 марта 2011 11:29
· Личное сообщение · #27

PE_Kill пишет:
Это довольно хреновое решение для лодыря, т.к. нужно будет висеть над жертвой до ее завершения, прятаться от обнаружения антидебаг трюками (для криптора так еще и драйвер нужно будет делать по хорошему) да и юзать дебагер для патча пары байт это ахтунг.

так вроде ж как можно и не висеть. Достаточно "дойти" до ЕР/TLS(антиотладка не успеет активизироваться), подсмотреть по какому адресу загружена база, после чего сделать детач, а дальше по сценарию: ReadProcessMemory/WriteProcessMemory. Насчёт PEB.BeingDebugged не могу сказать останется ли флажок выставленным после детача или нет, но обычно никаких проблем с его снятием не было.

-----
все багрепорты - в личные сообщения




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

Создано: 01 марта 2011 11:46
· Личное сообщение · #28

Зачем висеть? Получил imagebase и закрыл, а дальше как обычно.

Вариант 2
CreateProcess(fpath, 0,0,0,0,CREATE_SUSPENDED, 0,0, &sinfo, &pinfo)
ResumeThread(pinfo.hThread);
do{
Sleep(10);
}while(0==context.Eip);
по context.Eip вычисляем imagebase




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

Создано: 01 марта 2011 11:56 · Поправил: PE_Kill
· Личное сообщение · #29

DebugActiveProcessStop поддерживается исключительно начиная с Windows XP. Ожидание контекста процесса не всегда приемлимо, уж лучше инжектить код в выделенную память, чтобы он сам внутри процесса всё сделал.

Хе хе, по поводу получить список модулей в замороженном процессе я погорячился, оказывается в замороженном состоянии PEB почти не инициализирован, а LDR_DATA вообще NULL.

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





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

Создано: 01 марта 2011 14:28
· Личное сообщение · #30

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

ef5e_01.03.2011_CRACKLAB.rU.tgz - test.rar

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



. 1 . 2 . >>
 eXeL@B —› Программирование —› Loader + WriteProcessMemory в Windows7 x64
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


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