Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Массив байт как процедура, как ? 
:(
    Опции темы
ShadowDancer
Дата 8.7.2008, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 15.6.2006

Репутация: нет
Всего: нет



Возможно ли сделать вот что-то такое:
Код

type
  TBufProc = procedure;

var
  buf: array of byte;
  Proc: TBufProc;
begin
//заполняем массив байтами
{так будет выглядеть вызов MessageBox в байтовом представлении (код дизасемблен из подопытной программы, адрес вызова MessageBox разумеется определяется динамически)

($6A $00 $A1 $64 $66 $00 $00 $50
$68 $B0 $41 $40 $00 $6A $00 $E8
$40 $FB $FF $FF)

Этими байтами я забиваю массив, потом:}
 //указываю адрес "процедуры" и пытаюсь её запустить
 @Proc := @buf;
 Proc;


разумеется она у меня не запускается. Собсна вопрос, как сделать процедуру из массива байт и вызвать её ?
PM MAIL   Вверх
Riply
Дата 8.7.2008, 05:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(ShadowDancer @  8.7.2008,  00:57 Найти цитируемый пост)
Собсна вопрос, как сделать процедуру из массива байт и вызвать её ? 


Писала, засыпая на ходу.
Так что за ляпы и "страшность" кода прошу не взыскивать smile

Код

type
 PFunctTable = ^TFunctTable;
 TFunctTable = packed record
  hNtDLL: HMODULE;
  _RtlInitUnicodeString: procedure(Buffer : PUNICODE_STRING; Source : PWideChar); stdcall;
  _RtlInitAnsiString: procedure(var Buffer: TANSI_STRING; Source: PAnsiChar); stdcall;
  _LdrGetDllHandle: function(Path: LPWSTR; DllCharacteristics: PULONG; DllName: PUNICODE_STRING; DllHandle: PHandle): NTSTATUS; stdcall;
  _LdrGetProcedureAddress: function(ImageBase: PVOID; ProcName: PANSI_STRING; ProcedureOrdinalValue: PULONG; ProcedureAddress: PPvoid): NTSTATUS; stdcall;
  function InitSelf: DWord;
 end;

function TFunctTable.InitSelf: DWord;
begin
 FillChar(Self, SizeOf(TFunctTable), 0);
 hNtDLL := GetModuleHandle('ntdll.dll');
 if hNtDLL <> 0 then
  begin
   @_RtlInitUnicodeString := GetProcAddress(hNtDLL, 'RtlInitUnicodeString');
   @_RtlInitAnsiString := GetProcAddress(hNtDLL, 'RtlInitAnsiString');
   @_LdrGetDllHandle := GetProcAddress(hNtDLL, 'LdrGetDllHandle');
   @_LdrGetProcedureAddress := GetProcAddress(hNtDLL, 'LdrGetProcedureAddress');
   if Assigned(@_RtlInitUnicodeString) and Assigned(@_LdrGetDllHandle)
      and Assigned(@_RtlInitAnsiString) and Assigned(@_LdrGetProcedureAddress)
    then Result := ERROR_SUCCESS
    else Result := GetLastError;
  end
 else Result := GetLastError;
end;

type
 PInjectInfo = ^TInjectInfo;
 TInjectInfo = packed record
  FuntionsTable: TFunctTable;
  hInjectLib: HMODULE;
  function pInjectTreadCode: Pointer;
 end;

type
 TMessBox_Proc = procedure(pInfo: PInjectInfo);

function TInjectInfo.pInjectTreadCode: Pointer;
begin
 Result := Pointer(DWord(@Self) + SizeOf(TInjectInfo));
end;

procedure Proc_MessBox(pInfo: PInjectInfo);
const
 user32_LibName: PWideChar  = 'user32.dll';
 sMessageBoxW: PChar        = 'MessageBoxW';
var
 user32_U: UNICODE_STRING;
 MessBox_A: ANSI_STRING;
 RetStatus: NTSTATUS;
 _MessageBoxW: function(hWnd: HWND; lpText, lpCaption: PWideChar; uType: UINT): Integer; stdcall;
begin
 with pInfo^, FuntionsTable do
  begin
   _RtlInitUnicodeString(@user32_U, user32_LibName);
   RetStatus := _LdrGetDllHandle(nil, nil, @user32_U, @hInjectLib);
   if RetStatus >= 0 then
    begin
     _RtlInitAnsiString(MessBox_A, sMessageBoxW);
     RetStatus := _LdrGetProcedureAddress(Pointer(hInjectLib), @MessBox_A, nil, @@_MessageBoxW);
     if RetStatus >= 0 then _MessageBoxW(0, user32_LibName, user32_LibName, 0);
    end;
  end;
end;

function _ProcBaseCodeSize: DWord;
begin
 Result := DWord(@_ProcBaseCodeSize) - DWord(@Proc_MessBox);
end;

function InjectInfo_AllocMem(var pInfo: PInjectInfo; const pRemoteThread: Pointer; const cbCodeSize: DWord): DWord;
begin
 Result := cbCodeSize + SizeOf(TInjectInfo);
 ReallocMem(pInfo, cbCodeSize + SizeOf(TInjectInfo));
 Move(pRemoteThread^, pInfo.pInjectTreadCode^, cbCodeSize);
end;

procedure SaveLoadMessBoxProc(const FileName: string);
var
 pInfo: PInjectInfo;
 TmpSize: DWord;
 _ProcBase: TMessBox_Proc;
begin
 if FileExists(FileName) then
  with TMemoryStream.Create do
   try
    LoadFromFile(FileName);
    pInfo := Memory;
    @_ProcBase := pInfo.pInjectTreadCode;
     _ProcBase(pInfo);
   finally
    Free;
   end
 else
  begin
   pInfo := nil;
   TmpSize := InjectInfo_AllocMem(pInfo, @Proc_MessBox, _ProcBaseCodeSize);
   try
    FillChar(pInfo^, SizeOf(TInjectInfo), 0);
    if pInfo.FuntionsTable.InitSelf = ERROR_SUCCESS then
     with TFileStream.Create(FileName, fmCreate) do
      try
       Write(pInfo^, TmpSize);
      finally
       Free;
      end;
   finally
    ReallocMem(pInfo, 0);
   end;
  end;
end;

procedure TMainForm.SpeedButton3Click(Sender: TObject);
begin
 SaveLoadMessBoxProc('E:\Delete Files\TempProc');
end;


Добавлено через 3 минуты и 53 секунды
P.S.
 Некоторые процедуры не рекомендуется менять местами.
 Ну, вообщем, если кто и будет разбираться, то поймет какие  smile 
PM MAIL   Вверх
CodeMonkey
Дата 8.7.2008, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Всё правильно делали. Ну почти....
@buf - это адрес переменной buf, а не адрес массива. 
Нужно было:
Код
Proc := @(buf[0]);




--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
v00d00
Дата 9.7.2008, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 28.12.2005

Репутация: нет
Всего: нет



Постойте.
Мы ведь определяем процедуру (массив) в куче, разве программа сможет исполнить код, который находиться в сегменте данных?
PM MAIL   Вверх
Riply
Дата 9.7.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(v00d00 @  9.7.2008,  10:15 Найти цитируемый пост)
Мы ведь определяем процедуру (массив) в куче, разве программа сможет исполнить код, который находиться в сегменте данных? 


Не поняла. Можно объяснить "на пальцах" ?


P.S.
 Разумеется, я напартачила в коде.
 Не стоит объявлять user32_LibName и sMessageBoxW внутри Proc_MessBox.
 Лучше их объявить в TInjectInfo как array[0..MAX_MODULE_NAME] of WideChar(Char) и заполнять динамически.

Sorry.


PM MAIL   Вверх
W4FhLF
Дата 9.7.2008, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



В этой теме я описывал решение похожей ситуации. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0500 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.