delphi4arab منتديات دلفي للعرب
تغيير قيمة معينة فى ملف عن طريق دالة معينة - نسخة قابلة للطباعة

+- delphi4arab منتديات دلفي للعرب (https://delphi4arab.net/forum)
+-- قسم : منتديات دلفي للعرب التعليمية (https://delphi4arab.net/forum/forumdisplay.php?fid=3)
+--- قسم : سؤال و جواب حول دلفي (https://delphi4arab.net/forum/forumdisplay.php?fid=15)
+--- الموضوع : تغيير قيمة معينة فى ملف عن طريق دالة معينة (/showthread.php?tid=1871)

الصفحات: 1 2


تغيير قيمة معينة فى ملف عن طريق دالة معينة - hanipino - 05-04-2010

السلام عليكم

اخوانى كيف اغيير قيمة معينة فى ملف تنفيدى لاكن بشرط ... استعمال هده الدالة .
المشكل هو كيف الحصول على BaseAddress لهده القيمة (برمجيا).
PHP كود :
procedure MemoryPatch(sExecutableFilePath :string; Patch: Byte; BaseAddress: Integer; nSize, BytesCount: Cardinal);
var
  
ProcessInfo: TProcessInformation;
  
StpInfo: TStartupInfo;
  
buf: PChar;
begin
  FillChar
(StpInfo,SizeOf(TStartupInfo), #0);
  
FillChar(ProcessInfo,SizeOf(TProcessInformation), #0);

  
if not CreateProcess(PChar(sExecutableFilePath),
                       
Nil, Nil, Nil, False, CREATE_SUSPENDED,
                       
Nil, Nil, StpInfo, ProcessInfo)
  
then
    MessageBox
(0, 'Program not found!', '', MB_OK + MB_ICONWARNING)
  else
  
begin
    GetMem
(buf, 1);
    
buf^ := Chr(Patch);
    
WriteProcessMemory(ProcessInfo.hProcess, Ptr(BaseAddress), buf, nSize, BytesCount);
    
FreeMem(buf);
    
ResumeThread(ProcessInfo.hThread);
  
end;
end; 

--- يوجد فى المنتدى كيفية استثمار هده الدالة ---

مثلا هده القيمة .
[صورة: 1270473925.jpg]



تغيير قيمة معينة فى ملف عن طريق دالة معينة - TF6M - 05-04-2010

و عليكم السلام و رحمة الله و بركاته

- أخي hanipino , الدالة عبارة عن Loader أي أنها تقوم بتحميل sExecutableFilePath
الى الذاكرة بواسطة CreateProcess .
الهدف منها تغير Byte من البرنامج المحمل (أي عمل Patching) بواسطة WriteProcessMemory
في الذاكرة (يعني نتعامل مع العناوين كـ VA = virtual address) .

مواضيع ذات صلة :

1- Api Hook مثال بسيط, Hook للدالة TerminateProcess , مثال رائع WriteProcessMemory
2- رفع اللبس عن Rva,Va و الأوفسيت

- BaseAddress # ImageBase , راجع Image_Nt_Headers المهم يجب أن تعرف بنية PE Header
3- ستجد كتاب بالمرفقات , مفيد جدا ! .


مثال توضيحي :

ستجد أن RegMe , يطلب كود التسجيل , الأن نفذ الـ Loder , ثم قم بإدخال أي User Name
و أي Pass Word (عشوائيا) , الأن أصبح البرنامج مسجل:tong: .


[صورة: 4564545.gif]

ملاحظة : الـ Loder , للـ الأخ Kachwahed , فقط قمت بتبديل موضع القفزات .

بالتوفيق ,,


تغيير قيمة معينة فى ملف عن طريق دالة معينة - kachwahed - 05-04-2010

وعليكم السلام ورحمة الله
إقتباس :المشكل هو كيف الحصول على BaseAddress لهده القيمة (برمجيا).
تم الحصول على BaseAddress من هنا:
[صورة: 2yugapg.jpg]
القيمة التي أصبحت 74 هي PokeValue. وهي قيمة واحدة لذلك NumberOfBytes =1
ملاحظة: تغيرت العناوين بعد الـ Compile بدلفي 7 كما في الصورة.
إقتباس :برمجيا
ممم... لكن على أساس ماذا؟
ربما يساعدك هذا:
مثال للحصول على EP برمجيا:
PHP كود :
const
  
// PE header constants
  
CENEWHDR = $003C;  // offset of new EXE header
  
CEMAGIC  = $5A4D;  // old EXE magic id:  'MZ'
  
CPEMAGIC = $4550;  // NT portable executable

function GetImageNtHeaders(module: dword) : PImageNtHeaders;
begin
  result 
:= nil;
  try
    if 
word(pointer(module)^) = CEMAGIC then begin
      result 
:= pointer(module + dword(pointer(module + CENEWHDR)^));
      if 
result^.signature <> CPEMAGIC then
        result 
:= nil;
    
end;
  
except result := nil end;
end;

function 
GetEntryPoint(module: dword) : pointer;
var 
nh : PImageNtHeaders;
begin
  nh 
:= GetImageNtHeaders(module);
  if (
nh <> nil) and (nh^.OptionalHeader.AddressOfEntryPoint <> 0) then
    dword
(result) := module + nh^.OptionalHeader.AddressOfEntryPoint
  
else
    
result := nil;
end; 
بالتوفيق.



تغيير قيمة معينة فى ملف عن طريق دالة معينة - TF6M - 05-04-2010

...
الأن أوضحت الكود , كنت أظن أن Base Address هي Image Base ؟؟؟ في المثال الذي وضعته أنت ,
لكن أخي kachwahed أليس العنوان المشار إليه Va ؟؟ أم أن له تسمية أخرى (Base Address).
بالتوفيق ,,



تغيير قيمة معينة فى ملف عن طريق دالة معينة - hanipino - 05-04-2010

سلام عليكم
إقتباس :لكن أخي kachwahed أليس العنوان المشار إليه Va ؟؟ أم أن له تسمية أخرى (Base Address).

نعم هى Va لاكن اخدت اسم Base Address فى الدالة MemoryPatch لانها استعملت فى البرمتر الثانى للدالة
WriteProcessMemory الدى يحمل نفس الاسم ... فقط .

[صورة: 1270527017.jpg]

كود :
تم الحصول على BaseAddress من هنا:

والله اعلم يمكن الحصول عليها من خلال موقع البايت فى الملف التنفيدى

مثلا فى المثال الدى الرفقته اخى كاش واحد المسمى PatchMe.exe عند تنفيد الدالة RvaToOffset عليه ستعطى موقع البايت التى تؤشر عيه VA و هو 327165
الان افتح الملف PatchMe.exe بمحرر هكس و دهب الى هدا الموقع ستجد تلك القيمة تغيرت

[صورة: 1270528990.jpg]

و بالتالى بطريقة عكسية يمكن الحصول على VA من موقع البايت مثلا

كود :
Edit1.text := InttoHex(327165, 8) ;

ثم نستعمل القيمة المخزة فى EDIT1 فى الدالة offset2rva فنحصل على VA
اى يمكن الحصول على VA من موقع البايت و الله اعلم .
لاكن المشكل الدى واجهنى هو ادا كان موقع هدا البايت اصغر من 18954 ... لا احصل على VA الصحيح


تغيير قيمة معينة فى ملف عن طريق دالة معينة - kachwahed - 05-04-2010

الـ VA هي العنوان الافتراضي، تستخدم عند إنشاء Loader ، وهي التي تظهر في Disassembler
الـ Offset هي عنوان البايت على القرص وهي التي تستخدم عند الـ Patch، وهي التي تستخدم في محررات الـ Hex

الـ Relative Virtual Address (أو RVA) هي عنوان VA بعد تحميله في الذاكرة (أي بزيادة ImageBase)

لتسهيل التحويل بين VA و RVA و Offset استخدم بريمج LordPE كما يلي:
للتحويل من VA إلى غيره:
[صورة: 13ygw0h.jpg]
أنقر على زر آخر لتحويل باتجاه آخر Smile

إقتباس :اقتباس:
لكن أخي kachwahed أليس العنوان المشار إليه Va ؟؟ أم أن له تسمية أخرى (Base Address).
نعم هى Va لاكن اخدت اسم Base Address فى الدالة MemoryPatch لانها استعملت فى البرمتر الثانى للدالة
WriteProcessMemory الدى يحمل نفس الاسم ... فقط .
تماما كان علي اختيار اسم آخر للمتغير Big Grin
بالتوفيق.



تغيير قيمة معينة فى ملف عن طريق دالة معينة - TF6M - 05-04-2010

نعم صحيح يمكن القول أن Virtual Address = Base Address , إستنتجتها من VirtualAllocEx .
بالتوفيق ,,



تغيير قيمة معينة فى ملف عن طريق دالة معينة - hanipino - 05-04-2010

نعم اخوانى
اختلطت على الامور ... Smile

1- نريد الحصول على va برمجيا اى (va ل بايت معين على اساس موقعه مثلا البايت الاول .. 2 .. 3 .. 4 )
اولا نحسب offset ثم نحول هدا offset الى va

---
حساب offset سهل جدا
كود :
مثلا offset ل البايت الاول Edit1.text := InttoHex(1, 8) ; offset ل البايت الثانى Edit1.text := InttoHex(2, 8) ;

ثم نحول هدا offset الى va ... انا استعملت هده الدالة Offset2Rva من اسمها يتضح انها تحول الى Rva لكنها تعطى نتائج va (لا علينا المهم اننا نحتاج va)
PHP كود :
function Offset2Rva (pAddrOfFile: Pointer; dwRva : dword ):dword;
type
   IMAGE_SECTION_HEADER 
= packed record
    Name            
: packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
    
PhysicalAddress : DWORD;
    
VirtualAddress  : DWORD;
    
SizeOfRawData   : DWORD;
    
PointerToRawData : DWORD;
    
PointerToRelocations : DWORD;
    
PointerToLinenumbers : DWORD;
    
NumberOfRelocations : WORD;
    
NumberOfLinenumbers : WORD;
    
Characteristics : DWORD;
  
end;
  
PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
  
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
  
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;

var
  
i : byte;
  
sectionh : PIMAGE_SECTION_HEADER;
  
dosh : PIMAGE_DOS_HEADER;
  
peh : PIMAGE_NT_HEADERS;
begin
  
if dwRva = 0 then
  begin
    result
:=dwRva;
    exit;
  
end;
  
dosh     := PIMAGE_DOS_HEADER(pAddrOfFile);
  
peh      := PIMAGE_NT_HEADERS(Longword(dosh) + Longword(dosh._lfanew));
  
Sectionh := PIMAGE_SECTION_HEADER(peh);
  
inc(pimage_nt_headers(Sectionh));
  
// dwRva := dwRva - peh.OptionalHeader.ImageBase;
  
for i:=peh.FileHeader.NumberOfSections Downto 1 do
  
begin
    
if (dwRva >= Sectionh.VirtualAddress) and
      (
dwRva < (Sectionh.VirtualAddress + Sectionh.PhysicalAddress))
    
then break;
    
inc(sectionh);
  
end;
  
Result := dwRva + peh.OptionalHeader.ImageBase + sectionh.VirtualAddress - sectionh.PointerToRawData;
end; 

الان المشكل الدى يقع هو ادا اردنا الحصول على va لبايت موقعه قبل 4096 النتائج تكون خاطئة فى غير دالك النتائج صحيحة ... للمقارنة نستعمل البرنامج الدى اشار اليه اخى كاش واحد بارك الله فيه .
مثلا الحصول على va للبايت الاول نقوم بحساب
كود :
InttoHex(1, 8) ;
ونسجله فى حانة ال offset لبرنامج LordPE ونقارن مع نتائج هدا الرفق .

:bye1:


تغيير قيمة معينة فى ملف عن طريق دالة معينة - TF6M - 05-04-2010

أخي hanipino , بغض النظر عن من&إلى التحويل Offset&RVA , لكن كيف عرفت الـ Target Offset ؟
هل تستعمل منقح يعمل بالـ Offset ؟, نقوم بدراسة الملف بـ OllyDbg (أشهر
debugger) عند معرفة مكان
تغير القفزة مثلا ؟؟ ... ستكون بالـ VA , لديك قاعدة بسيطة :


PHP كود :
VA = RVA + ImageBase
Target_OFFSET 
= Targer_RVA – Section_RVA + Section_OFFSET
Target_OFFSET 
= Targer_VA – Section_VA + Section_OFFSET 

كل ما قلته لك , موجود في المشاركة رقم #2 .

بالتوفيق ,,


تغيير قيمة معينة فى ملف عن طريق دالة معينة - hanipino - 06-04-2010

Smile لم افهمك اخى tf6m

المهم ...

نفترض انه لديك ملف تنفيدى و انت تعلم لو غيرت البايت العاشر مثلا سيصبح البرنامج Registred
هل تستطيع تحميل هدا الملف للداكرة وتغير دالك البايت فى الداكرة

بشرط دون استعمال OllyDbg او اى برنامج اخر من هدا النوع .اى (عندك ملف تنفيدى و محرر هكس و دالفى ).