المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
السلام عليكم ورحمة الله وبركاتة
قبل فترة عملت برنامج ... شبيه بـ Cheat Engine وكان الهدف لزيادة الخبرة وإنتاج برنامج غير مكشوف من بعض الحمايات ...
ولكن كان يحتوي على بعض الاخطاء التي بعض الأوقات تسبب تدمير (Crash) للبرنامج رغم ان البرنامج
لا يحتوي على اي خطاء برمجي ...
حيث اني كنت اقرء الذاكرة واعيد العنوان والقيمة في Array إذا تطباقت القيمة التي تم قرائتها مع
القيمة التي ابحث عنها ... وعملت دالة تقوم بذلك لتسهيل العملية ... وكتبتها بهذا الشكل :
PHP كود : type dwArray = Array[0..1] of array of Cardinal; function FindValueDWORD(hProcess : NativeUInt; dwStartAddress, dwEndAddress : Cardinal; Value : Cardinal): dwArray ; var TempAddress : Cardinal; I : Integer; BytesRead : NativeUInt; dwResult : Cardinal; LenArray : Integer; begin LenArray := 0; SetLength(Result[0],1); SetLength(Result[1],1);
if not ( hProcess <> 0 ) then Exit; if ( dwStartAddress > dwEndAddress ) then begin TempAddress := dwEndAddress; dwEndAddress := dwStartAddress; dwStartAddress := TempAddress; end;
SetLength(Result[0],0); SetLength(Result[1],0);
for I := dwStartAddress to dwEndAddress do begin ReadProcessMemory(hProcess, Pointer(I), @dwResult, 4, BytesRead); if ( dwResult = Value ) then begin LenArray := LenArray + 1; SetLength(Result[0],LenArray); SetLength(Result[1],LenArray); Result[0][LenArray -1] := I; Result[1][LenArray -1] := dwResult; end; end; end;
لكن عندما اقارن سرعة البحث في برنامجي وسرعة البحث في برنامج Cheat Engine
اجد برنامج Cheat Engine سريع جداً بينما برنامجي بطئ مقارنة مع Cheat Engine
وهنا اعيد طرح السؤال ... ما هي اسرع الطرق لعملية بحث في الذاكرة ؟
اتمنى وضحت المطلوب ...
وشكراً لحسن القراءة
والسلام عليكم ورحمة الله وبركاتة
المشاركات : 632
المواضيع 66
:
: 6
الإنتساب : Jul 2010
بالطبع يا أخي ستكون الدالة بطيئة لسببين
السبب الأول أنك تستخدم مصفوفة ذات بعد ثنائي
السبب الثاني الحلقة التي تستخدمها لقراءة الذاكرة
-------------------------------------
ليس هناك داعي لمصفوفة ثنائية طالما قيمة Value ثابة !!
+ القراءة من الذاكرة باستخدام حلقة سيبطأ الدالة
-----------------------------------
هذا مثال سريع :
PHP كود : type dwArray2= array of Cardinal; function FindValueDWORD2(hProcess : Cardinal; dwStartAddress, dwEndAddress : Cardinal; Value : Integer): dwArray2 ; type PCardinalArray = ^TCardinalArray; TCardinalArray = array[0..16383] of Cardinal ; var nCount,i,Len:Integer; dwResult:PCardinalArray; TempAddress:Cardinal; nb:Cardinal;
begin nCount:=0; SetLength(Result,nCount+1); Result[nCount]:=0; if hProcess = 0 then Exit; if ( dwStartAddress > dwEndAddress ) then begin TempAddress := dwEndAddress; dwEndAddress := dwStartAddress; dwStartAddress := TempAddress; end; Len:=dwEndAddress -dwStartAddress;
GetMem(dwResult,Len); ReadProcessMemory(hProcess, Pointer(dwStartAddress), dwResult,Len, nb); for i:=0 to nb do begin if (dwResult[i] = Value) then begin Inc(nCount); SetLength(Result,nCount); Result[nCount-1]:=dwStartAddress+i; end; end; FreeMem(dwResult,Len); end;
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
السلام عليكم ...
اعرف ان الرد اتى متأخراً , لاني انشغلت في اموار آخرى ...
احببت ان اسئل عن الدالة GetMem ما وضيفته بالضبط ؟
هل لك ان تشرح لي الطريقة المتبعه في جلب القيمة في الدالة التي كتبتها .. لان لدي بعض الاستفهامات
وشكراً لك من جديد اخي SMP3
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
السلام عليكم ...
لدي سؤال آخر وهو عن هذا التعريف :
PHP كود : type PCardinalArray = ^TCardinalArray; TCardinalArray = array[0..16383] of Cardinal ;
لماذا وضعت القيمة 16383 تحديداً ؟؟
المشاركات : 632
المواضيع 66
:
: 6
الإنتساب : Jul 2010
ALmuhhnad كتب :هل لك ان تشرح لي الطريقة المتبعه في جلب القيمة في الدالة التي كتبتها .. الدالة GetMem تقوم بحجز مكان لمؤشر في الذاكرة
عند تعاملنا مع المؤشرات يجب أن نقوم بحجز مكان لها في الذاكرة تماما مثل SetLength
-------------------
نفس التمرير للدالة
ALmuhhnad كتب :لدي سؤال آخر وهو عن هذا التعريف : أنت استخدمت 2 بايت للقراءة لأنك تقوم بالقراءة باستخدام Loop .. أما استخدامي 16383 فهو بسبب قراءة الذاكرة بحجم معين وتخزن القيمة في مصفوفة .. يعني القراءة مرة واحدة لذلك يجب أن تكون المصفوفة طويلة .
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
إقتباس :أنت استخدمت 2 بايت للقراءة لأنك تقوم بالقراءة باستخدام Loop ..
انا استخدمت 4 بايت ... لكن بسبب الـ loop على ما اضن اني اقرى بايت بايت ... أي اني اقرى 4 بايت وبعد لذلك اتأكد من مطابقتها للقيمة
ثم اقرى العنوان الذي يليه ببايت واحد ...إلخ
إقتباس :أما استخدامي 16383 فهو بسبب قراءة الذاكرة بحجم معين وتخزن القيمة في مصفوفة
طيب لو حصل وان كان المراد قرائته اطول من الطول المحدد ... ماذا افعل لكي اضع الطول مفتوح وعلى حسب الـ dwStartAddress
و dwEndAddress ?
المشاركات : 632
المواضيع 66
:
: 6
الإنتساب : Jul 2010
ALmuhhnad كتب :انا استخدمت 4 بايت ... لكن بسبب الـ loop على ما اضن اني اقرى بايت بايت ... أي اني اقرى 4 بايت وبعد لذلك اتأكد من مطابقتها للقيمة
ثم اقرى العنوان الذي يليه ببايت واحد ...إلخ
طيب لو حصل وان كان المراد قرائته اطول من الطول المحدد ... ماذا افعل لكي اضع الطول مفتوح وعلى حسب الـ dwStartAddress
و dwEndAddress ?
في هذه الحالة عليك باستخدام Dynamic Arrays
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
هل تقصد بـ Dynamic Arrays هكذا :
PHP كود : dwArray2 = array of Cardinal;
عذراً فانا لا احفظ المصطلحات العلمية كثيراً P:
ايضاً عند إستعمالي بهذه الطريقة سيحصل خطاء في GetMem
ايضاً يا حبذ ان تكتب المثال في XE3 لاني اواجه صعوبة في تحولي الكود @@"
فالمصفوفات لم يسبق لي ان تعاملت معها ... إلا في هذا المثال ... لذلك كان احد اهدافي ان ازيد خبرتي
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
نسيت ان اذكر .... :
( الكود يعمل مع d7 )
في الرد السابق كنت اتكلم عن xe3 ...
المشاركات : 306
المواضيع 45
:
: 0
الإنتساب : Jul 2012
السلام عليكم ...
الحمد لله استطعت بفضل الله ثم مساعدت اخي المبرمج SMP3 وضع دالة للقراءة ( لم اجرب سرعتها بعد )
هذه الدالة بـ Delphi XE3 :
PHP كود : type DWORDOfArray = Array of Cardinal; ByteOfArray = array of byte; function FindVale_Byte(hProcess, dwStartAddress, dwEndAddress : Cardinal; Value : Byte; ProgressSearching : TGauge): DWORDOfArray; var I, Len, iCount : Integer; NumReadBytes : NativeUInt; TempAddress : Cardinal; aResult : ByteOfArray; begin iCount := 0; SetLength(Result,iCount + 1); Result[iCount] := 0; if hProcess = 0 then Exit; if dwStartAddress > dwEndAddress then begin TempAddress := dwEndAddress; dwEndAddress := dwStartAddress; dwStartAddress := TempAddress; end; Len := (dwEndAddress - dwStartAddress) + 1; SetLength(aResult,Len); ReadProcessMemory(hProcess,Pointer(dwStartAddress),aResult,Len,NumReadBytes); ProgressSearching.MaxValue := NumReadBytes; ProgressSearching.Progress := 0; ProgressSearching.MinValue := ProgressSearching.Progress; for I := 0 to NumReadBytes do begin if aResult[i] = Value then begin Inc(iCount); SetLength(Result,iCount); Result[iCount-1] := dwStartAddress + i; end; ProgressSearching.Progress := i; end; end;
اضفت لها اوامر إخبار المستخدم اين وصل البحث من خلال المكون TGauge
طريقة الإستعمال :
PHP كود : procedure TMain.btnFirstScanClick(Sender: TObject); var I, Len : Integer; hProcess : Cardinal; dwResult : DWORDOfArray; StartAddress, EndAddress : Cardinal; iValue : integer; begin iValue := StrToInt(edtValue.Text); StartAddress := sHexToInt(edtStartAddress.Text); EndAddress := sHexToInt(edtEndAddress.Text); hProcess := OpenProcess(PROCESS_VM_READ,False,StrToInt(edtPID.Text)); dwResult := FindVale_Byte(hProcess,StartAddress,EndAddress,iValue,gagPrograssSreaching); Len := Length(dwResult); for I := 0 to Len -1 do begin Memo1.Lines.Add(IntToHex(dwResult[i],8) + ' = ' + IntToStr(iValue)); end; end;
الآن ما الملاحظات على الدالة  إن امكن ...
وبعد قليل ساجرب سرعة الدالة
|