WriteProcessMemory w praktyce (wlasny loader)

0

Witam,

jak uzyc funkcji WriteProcessMemory w praktyce? (http://4programmers.net/Delphi/WriteProcessMemory)

chodzi mi o to zeby program tworzyl nowy proces przez funkcje API CreateProcess z parametrem "suspend",
nastepnie uzywal funkcji WriteProcessMemory, w taki sposob zeby zmienial pewna instrukcje pod adresem 0040138C na E8 F4 00 00 00 90 (w hexie)
a na koncu uzywal funckcji ResumeThread

jak to napisac?

pozdrawiam

0

Z czym masz problem konkretniej ? Bo wszystko czego chcesz już wymyśliłeś.

0

po prostu nie wiem jak napisac kod w Delphi

0

Mam takie pytanko generalnie chodzi mi o uruchomienie programu który jest w zasobach jakiegoś exe który nie moze być nigdzie zapisany. ale niestety nie jest to takie łatwe ponieważ wiąze sie z wygenerowaniem wirtualnego napędu. A w róznych systemach jest to troche inaczej. poza tym czesto wiaże sie z przechodzeniem jakis wizardów z kreowaniem wirtualnych dysków a potem trzeba je usuwac to troche trwa itp... Wiec po 2 dniach czytania zmieniłem koncepcje ale niestety nie mam doswiadczenia z pisaniem w winapi a zapewne to nie jest taki trudne, mam nadziej ze ktoś mi podsunie kilka linijek. Oto koncepcja :

Mam swój program gotowy działający sa tam juz procedury zabezpieczające itp...

  • chce uruchomic ten program z parametrem suspened przed czymkolwiek initlilize itp.. moze byc przez inną aplikacje
  • nastepnie zrzucic ten proces do pliku podrodze go kryptując oczywiscie - kryptowanie mam zrobione ale nie wiem jak zrzucić
  • nastepnie dodac zakryptowany plik do zasobów lodera - to akurat umiem
  • naspepnie loader po uruchomieniu i zrobieniu kilku procedur sprawdzajacych ładuje plik ze swoich zasobów do streamu - to akurat nie problem
  • nastepnie deszyfruje stream i ładuje do pamieci - deszyfrowanie w locie tez zrobione tylko nie wiem jak to załadować do pamieci
  • nastepnie odwiesza program i form sie pojawia - tego też nie wiem

aha chciabm tez zeby aplikacja znaczy ten odwieszany proces myslał ze jest w tym miejscu na dysku gdzie ten loader znaczy wywoluje w nim funkcje ExtractFilePath(Application.ExeName) moge ją zmienic na jakas która sobie poradzi z tym fantem
;)

0

Ten wątek ma prawie dokładnie 2 lata...

0

No i..., ale dotyczy mojego problemu wiec nie zakładam kolejnego :D nie chce zeby mi ktoś napisał żebym szukał na forum bo nie znalazłem innego tylko ten ;)

0

CreateProcess, GetProcessId, GetThreadId, SuspendThread, ReadProcessMemory, WriteProcessMemory, ResumeThread - mniej-więcej tyle. Opisy znajdziesz na msdn'ie(zaglądałeś tam wcześniej?). Zastosowanie na 4p i msdn'ie.

0
procedure TForm1.Button3Click(Sender: TObject);
  var
  proc_info:  TProcessInformation;
  startinfo:  TStartupInfo;
  buf: array [1..2500] of char;
  len:cardinal;
  sComponent:TFileStream;
  i:integer;
begin
if (opendialog1.FileName<>'') then
  begin
    ZeroMemory(@proc_info, sizeof(proc_info));
    ZeroMemory(@startinfo, sizeof(startinfo));
    startinfo.cb := sizeof(TStartupInfo);
    if CreateProcess(PChar(opendialog1.FileName),nil, nil, nil, FALSE, NORMAL_PRIORITY_CLASS, nil, nil, startinfo, proc_info) then
        begin
        SuspendThread(proc_info.hThread);
        readprocessmemory(proc_info.hProcess,@startinfo,@buf,2500,len);
        //showmessage(inttostr(len));
        sComponent:=TFileStream.Create(ExtractFilePath(Application.ExeName)+'dump.bin', fmCreate);
        for i:=0 to len do sComponent.Write(buf[i],  SizeOf(buf[i]));
        sComponent.Free;
        resumethread(proc_info.hThread);
        WaitForSingleObject(proc_info.hProcess, INFINITE);
        CloseHandle(proc_info.hThread);
        CloseHandle(proc_info.hProcess);
        end;
  end;
end;

Tak to wygląda i stoje aktualnie nad znalezieniem adresu z jakiego ma dumpowac wstawiałem tam @startinfo ale pobiera mi same zera :( nie wiem jak to obejsc w kazdym z opisów na google itp.. adres jest juz wstawiony nie wiem skąd :( NO chyba ze zupelnie cos zle zrobilem bo jak zrobilem dump zwiekszajac adres to caly czas mi dumpuje juz z 40mb same zera :/

0

bo wywołujesz readprocessmemory z nieprawidłowym uchwytem. potrzebujesz otworzyć proces z odpowiednimi uprawnieniami, zanim będziesz mógł cokolwiek odczytać z jego pamieci. to samo tyczy się startinfo, musisz je wypełnić sensownymi danymi... a nie wrzucasz wszędzie same zera i modlisz się, żeby Bóg natchnął Twój kod danymi.
tu masz przykład: ReadProcessMemory

0

ReadProcessMemory niestety ten kod zawiera bledy i nie funkcjonuje wiec jak sie na nim opieram tez nic sie nie dzieje, moze ktos ma jakis inny pomysł?

0

sam go pisałem, więc wiem, że nie ma błędów, a nawet - że zaryzykuję takie stwierdzenie - działa.

0

Hmmm skoro nikt nie poprawi mojego kodu to zacznę od poacztku. co robie zle ze mi sie proces nie uruchamia?

procedure TForm1.Button3Click(Sender: TObject);
  var
  proc_info:  TProcessInformation;
  startinfo:  TStartupInfo;
if (opendialog1.FileName<>'') then
  begin
    if CreateProcess(PChar(opendialog1.FileName),nil, nil, nil, FALSE, NORMAL_PRIORITY_CLASS, nil, nil, startinfo, proc_info) then
....

Getlasterror daje 998 - czyli "Invalid access to memory location."

0

nie powinno aby być

if (opendialog1.Execute) then

?
co siedzi w opendialog1.FileName?

0
procedure TForm1.Button3Click(Sender: TObject);
  var
  proc_info:  TProcessInformation;
  startinfo:  TStartupInfo;
begin
    if CreateProcess(PChar(ExtractFilePath(Application.ExeName)+'mojexe.exe'),nil, nil, nil, FALSE, NORMAL_PRIORITY_CLASS, nil, nil, startinfo, proc_info) then
....

Oki teraz bardziej przejzyscie. program ktory chce zrzucic znajduje sie w tym samym katalogu co program dumpujacy i ma nazwe mojeexe.exe . Po wywolniu otrzymuje ten sam blad 998 ;)

0

a co z
ZeroMemory(@proc_info, sizeof(proc_info));
ZeroMemory(@startinfo, sizeof(startinfo));
startinfo.cb := sizeof(TStartupInfo);
???

0

wczesniej zazuciles mi ze wypelniam pamiec zerami wiec teraz tego nie robie :)

0

o matko, nie chodzi o wypełnianie zerami czy siódemkami, tylko o zrozumienie tego, co robisz. jeśli nie wypełniasz odpowiednich pól odpowiednimi wartościami to efekty są takie jak widać.
jak nie umiesz takich podstaw, to nie wiem jak chcesz się zabierać za zapis i odczyt pamięci procesu - będziesz z każdą linijką kodu ganiać na forum? chociaż google użyj, 10 sekund i będziesz mieć gotowy, działający przykład.

0

Uwierz że szukałem informacji na ten temat i nie mogę znaleźć zanych podstaw na ten temat, rozumiem że dla ciebie to rzeczy o których nie warto pisać na forum ale niestety w faq ani artykułach ani w gotowcach nic na temat podstaw <ort>NIE MA</ort>. wiec prosę może wskażesz mi droge bo <ort>zabardzo </ort>nie wiem od czego zacząć <ort>poco </ort>jest to startup info itp... . Aha i <ort>prosił bym</ort> bardzo o napisanie na poczatku czy moja koncepcja zastopowania programu i uruchomienia na innym komputerze jest możliwa, <ort>tu dzież</ort> uruchomienia programu ze streamu jak <ort>zaczołem </ort>watek na "C# i .NET". Pozdrawiam i proszę o wyrozumiałość ;)

0

Dziekuję @ŁF sorry ze tak cię <ort>flustruje </ort>ale naprawde niektóre materiały są zbyt niejasne dla laików w temacie procesów i pamięci. Obecnie zastosowałem twoje podpowiedzi wygląda to jakoś ale jeszcez nie tak jakbym chciał, mianowicie dumpuje mi coś ale jakoś mało tego kod wygląda następująco:

procedure TForm1.Button3Click(Sender: TObject);
  var
  f:file;
  h2:thandle;
  proc_info:  TProcessInformation;
  startinfo:  TStartupInfo;
  memStart : pointer;
  memInfo : MEMORY_BASIC_INFORMATION;
  buf: array of byte;
  len:cardinal;
  sComponent:TFileStream;
  i,j:integer;
begin
if (opendialog1.FileName<>'') then
  begin
    assignfile(f,ExtractFilePath(Application.ExeName)+'dump.bin');
    rewrite(f);
    FillCHar(startinfo, SizeOf(startinfo), 0);
    FillCHar(proc_info, SizeOf(proc_info), 0);
    startinfo.cb := SizeOf(startinfo);
    if CreateProcess(nil,PChar(opendialog1.FileName), nil, nil, FALSE, PROCESS_VM_READ, nil, nil, startinfo, proc_info)then
    begin
    sleep(1000);
    memstart := pointer($20000);
      h2 := OpenProcess (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, proc_info.dwProcessId);
    while VirtualQueryEx(h2, memstart, memInfo, SizeOf(MEMORY_BASIC_INFORMATION)) = SizeOf(MEMORY_BASIC_INFORMATION) do
      begin
      if (meminfo.State = MEM_COMMIT) then
        begin
        setlength(buf,memInfo.RegionSize);
        if (ReadProcessMemory(h2, memInfo.BaseAddress, buf, memInfo.RegionSize, len)) then
          begin
          blockwrite(f,buf,sizeof(buf));
          end;
          buf := nil;
        end;
      integer(memstart) := integer(meminfo.BaseAddress) + meminfo.regionsize;
      end;
        CloseHandle(proc_info.hThread);

    end;
    closefile(f);
  end;
end;

przy opcji CREATE_SUSPENDED dumpuje mi oklo 7,5Kb a przy normalnym okolo 85Kb
przy czym proces zajmuje w pamieci po uruchomieniu przez dumper 22MB a przy cerate_suspended 70kb ,
Przy uruchomieniu normalnym exe w pamieci zajmuje 1,5 MB

gdzie robię błąd moze przy zapisie do pliku badz to nie powinno byc basic memory?

0

zwróć uwagę na:

  • memstart := pointer($20000); -> to powoduje, że pamięć nie jest czytana od początku. ustaw to na zero.
  • if (meminfo.State = MEM_COMMIT) then -> masz tylko jeden typ pamięci uwzględniany, zobacz jakie są możliwe stany pamięci i kopiuj wszystkie interesujące, nie tylko commit. stąd prawdopodobnie taka duża różnica, która być może też bierze się też z tej linijki: integer(memstart) := integer(meminfo.BaseAddress) + meminfo.regionsize;

natomiast to dość logiczne, że proces nieuruchomiony zajmuje mniej pamięci - nie zainicjował żadnych zmiennych i nie pobrał sobie pamięci dla różnego typu zmiennych dynamicznych.

więcej nie podpowiem, bo nie zagłębiałem się dalej w ten temat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1