Loading...

BTC Address to donate : [[address]]

Donation of [[value]] BTC Received. Thank You.
[[error]]

RaYm0n TeaM HITMAN HaCkEr
TeaM A
  • شكراً: 9
  • تم شكره 377 مرة في 115 مشاركة

السلام عليكم ورحمة الله وبركاته
بعد التحيه والسلام
اضع بين ايديكم بعض اساسيات التنقيح
هناك مثال يبين طرق التعامل مع التنقيح وكا نصيحة قم بتجريبها على ابسط الامثله الموجوده مثل المؤشرات والمصفوفات ...وغيرها لممارسة وحتى تكتمل الفائده ان شاء الله ...
مثال:
كود:
#include <stdio.h>
 int main()
 {
 int i;
 for(i=0; i < 10; i++)       // Loop 10 times.
 {
   printf("Hello, world!\n");  // put the string to the output.
 }
 return 0;                   // Tell OS the program exited without errors.
 }

يخبر المثال السابق المجمع الى تضمين مكتبة الدخل والخرج القياسي
standard input/output (I/O) بشخن الملف المسمى stdio المتواجد على المسار /usr/include/stdio.h .هذا الملف يعرف العديد من الثوابت و دوال النموذج الاولي prototypes ، في المثال السابق أستخدامنا الدالة printf() من مكتبة الخرج والدخل القياسي فأن prototype الدالة التي نحتاج هي printf() قبل استخدمها . باقي الكود يجب ان يكون واضح ولايحتاج الى شرح

الان نقوم بتصريف البرنامج
كود:
[email protected]:~/booksrc $ gcc firstprog.c
 [email protected]:~/booksrc $ ls -l a.out
 -rwxr-xr-x 1 reader reader 6621 2007-09-06 22:16 a.out
 [email protected]:~/booksrc $ ./a.out
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 Hello, world!
 [email protected]:~/booksrc $

نظرة عن قرب The Bigger Picture :

بعد التجميع بواسطة GNU
Compiler Collection (GCC) فإن تعليمات الملف الثنائي a.out's هي تعليمات
لغة الآله التي يفهمها المعالج ، دعنا نفحص هذا الملف القابل للتنفيذ
بإستخدام اداة objdump التابعة للمشروع GNU بفك الرئيسية عن طريق الامر
التالي :
كود:

08048374 <main>:
 8048374:       55                      push   %ebp
 8048375:       89 e5                   mov    %esp,%ebp
 8048377:       83 ec 08                sub    $0x8,%esp
 804837a:       83 e4 f0                and    $0xfffffff0,%esp
 804837d:       b8 00 00 00 00          mov    $0x0,%eax
 8048382:       29 c4                   sub    %eax,%esp
 8048384:       c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffc(%ebp)
 804838b:       83 7d fc 09             cmpl   $0x9,0xfffffffc(%ebp)
 804838f:       7e 02                   jle    8048393 <main+0x1f>
 8048391:       eb 13                   jmp    80483a6 <main+0x32>
 8048393:       c7 04 24 84 84 04 08    movl   $0x8048484,(%esp)
 804839a:       e8 01 ff ff ff          call   80482a0 <[email protected]>
 804839f:       8d 45 fc                lea    0xfffffffc(%ebp),%eax
 80483a2:       ff 00                   incl   (%eax)
 80483a4:       eb e5                   jmp    804838b <main+0x17>
 80483a6:       c9                      leave
 80483a7:       c3                      ret
 80483a8:       90                      nop
 80483a9:       90                      nop
 80483aa:       90                      nop
[email protected]:~/booksrc $
 [email protected]:~/booksrc $ objdump -D a.out | grep -A20 main.:

نجد في الايسار هي عناوين الذاكرة التي تبداء هنا مع 0x8048374 .و في الوسط هي البايتات لتعليمات لغة الآله لمعالج x86 وتمثل باسادس عشر ولكي يفهما CPU تحول الى الميزان الثنائي كالـ 0101010110001001111001011000001111101100111100001 ، فكود الآله يعرض البايتات في السادس عشر وكل تعليمة توضع في سطره الخاص .اما على اليمين فهي تعليمات الاسمبلي .
نلاحظ القيم وعنونة الذاكرة تستخدم الترميز السادس عشر على الترميز العشري ، والسبب في استخدام السادس عشر على الترميز العشري لتوافق مع البايت ففي هذة الحالة لايفيد الترميز العشري ويسبب تشويش لان الترقيم العشري من 0-9 وبعدها تتكرر القيم,11,1210 لذلك سوف نحتاج مابعد العدد 10 من إظافة extra symbol ، تشمل اتفاقية الترميز السادس عشر وضع A - F بدلاً من تمثيل 10 - 15 . وكما نعلم ان البايت من 8 bits ولكل بت له قيمة 0 أو 1 ، هكذا البايت له (2^8) قيمة محتملة أي تتراوح القيمة بين 0-256 وبإزتاد القيمة على 256 يسبب بحدوث فائض حسابي ، يوضع لكل بايت مع رقمين من السادس عشر هذا يعني لنبداء في العد بواسطة نظام السادس عشر
00, 01,02,03…0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2A, 2B, 2C, 2D, 2E, 2F, 30, 31…………………FF
نجد القيمة تتراوح بين 0 الى FF التي هي في العشري 255 ، بينما مع ثلاثة ارقام سادس عشر مثل 100،101 هي في العشري 256 ، 257 على التوالي .. الى اعلى قيمة التي هي FFF التي هي في العشري 4095 . ايضاً اعلى قيمة لاربعة ارقام سادس عشر FFFF في العشري هي 65535 . الامر يماثل مع عنوانه الذاكرة التي تأخذ 32-bits لتحديد والوصول الى العنوان في اربع بايت مجتمعه .
ان لغة الاسمبلي فقط لتذكر التعليمات المطابقة لتعليمات لغة الآله ، لغة الاسمبلي ماهي الا طريقة للمبرمجين لتمثيل تعليمات لغة الآله المعطاه الى المعالج ، ومن البداهي ان التعليمة ret اسهل من التعليمة 0xc3 أو 11000011 ، على خلاف لغة السي و اللغات المصرفه الاخرى ، تعليمات لغة الاسمبلي لها علاقة one-to-one مع تعليمات لغة الآله المقابله مثل mov و add ...الى اخر. فقط في لغة الاسمبلي لاتولد التوجيهات Directive الى كود الآلة المقابل لها وتستخدم فقط لغرض تنظيم التعليمات مثل END و ENDP و PROC و ORG .
تختلف معمارية المعالج من معالج الى اخر لذا تعليمات لغة الآله المعطى للمعالج تختلف بحسب معمارية المعالج المصمم له وبالمثل لغة الاسمبلي تختلف بحسب معمارية المعالج . بينما يمكن نظرياً انشاء الصيغة x86 assembly language syntax الخاصة بك تماماً في كيفية تمثيل تعلميات لغة الآله في أسلوب سهل مفضل متوافق مع الاتفاقية ، في الشائع يوجد نوعين او صياغتين رائيسين للغة الاسمبلي هما : AT&T syntax و Intel syntax ، ان الاسمبلي المشاهدة وقد فكت disassembly سابقاً هي ل AT&T syntax وهو الافتراضي (كما انة من السهل معرفة AT&T syntax التي دائماً يضمن الرموز % و $ ) بينما لعرض صيغة intel :
كود:
[email protected]:~/booksrc $ objdump -M intel -D a.out | grep -A20 main.:
08048374 <main>:
 8048374:       55                      push   ebp
 8048375:       89 e5                   mov    ebp,esp
 8048377:       83 ec 08                sub    esp,0x8
 804837a:       83 e4 f0                and    esp,0xfffffff0
 804837d:       b8 00 00 00 00          mov    eax,0x0
 8048382:       29 c4                   sub    esp,eax
 8048384:       c7 45 fc 00 00 00 00    mov    DWORD PTR [ebp-4],0x0
 804838b:       83 7d fc 09             cmp    DWORD PTR [ebp-4],0x9
 804838f:       7e 02                   jle    8048393 <main+0x1f>
 8048391:       eb 13                   jmp    80483a6 <main+0x32>
 8048393:       c7 04 24 84 84 04 08    mov    DWORD PTR [esp],0x8048484
 804839a:       e8 01 ff ff ff          call   80482a0 <[email protected]>
 804839f:       8d 45 fc                lea    eax,[ebp-4]
 80483a2:       ff 00                   inc    DWORD PTR [eax]
 80483a4:       eb e5                   jmp    804838b <main+0x17>
 80483a6:       c9                      leave
 80483a7:       c3                      ret
 80483a8:       90                      nop
 80483a9:       90                      nop
 80483aa:       90                      nop
[email protected]:~/booksrc $

يفضل الكثير صيغة انتل لانها اكثر سهوله ومفهومة

The x86 Processor

لدى المعالج x86 processor مجموعة من المتغيرات الخاصة تسمى بالمسجلات registers تستعملها اغلب التعليمات لقراءة وكتابة البيانات ، والمسجلات ذاكرة المعالج والتخزين فيها موقت حيث تجلب البيانات من الذاكرة الرئيسية الى مسجلات المعالج وتنفيذها في المعالج وعادتاً تصمم في دوائر القلابات .لمشاهدة مسجلات المعالج نستخدم برنامج التنقيح GDB التابع GNU . عموماً تستعمل المنقحات مثل GDB من قبل المبرمجين لتتبع البرامج المجمعة وفحص ذاكرة البرنامج ومشاهدة مسجلات المعالج ، من خلال المنقح يمكن مشاهدة التنفيذ من كل الزوايا وتوقيف البرنامج عند اي نقطة وتغير أي شيء اثناء التنقيح . ونشاهد فيما يلي حالة مسجلات المعالج قبل بدأ البرنامج .
كود:
[email protected]:~/booksrc $ gdb -q ./a.out
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) break main
Breakpoint 1 at 0x804837a
(gdb) run
Starting program: /home/reader/booksrc/a.out

Breakpoint 1, 0x0804837a in main ()
(gdb) info registers
eax            0xbffff894       -1073743724
ecx            0x48e0fe81       1222704769
edx            0x1      1
ebx            0xb7fd6ff4       -1208127500
esp            0xbffff800       0xbffff800
ebp            0xbffff808       0xbffff808
esi            0xb8000ce0       -1207956256
edi            0x0      0
eip            0x804837a        0x804837a <main+6>
eflags         0x286    [ PF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) quit
The program is running.  Exit anyway? (y or n) y
[email protected]:~/booksrc $

قبل تنفيذ الدالة main() يوقف البرنامج بعمل نقطة توقف breakpoint ، ثم الامر run يشغيل البرنامج ويتوقف على نقطة التوقف المحددة ، في هذة الاثناء عرض جميع مسجلات المعالج وحالاتهم الحالية .

Assembly Language

صيغة Intel تستخدم باستمرار ، لذلك لعمل اعدادات الصياغة داخال منقح GDB نستخدم الامر set disassembly intel او يمكن اختصارها بالامر set dis intel .
كود:
[email protected]:~/booksrc $ gdb -q
(gdb) set dis intel
(gdb) quit

ويمكنك ان تقوم بعمل الإعدادت في كل مرة يبداء المنقح في التشغيل وذلك بوضع هذا الامر في ملف .gdbinit في الهوم الخاصة بك وذلك كما يلي :

كود:
[email protected]:~/booksrc $ cat ~/.gdbinit
set dis intel
[email protected]:~/booksrc $
 [email protected]:~/booksrc $ echo "set dis intel" > ~/.gdbinit

دعنا نفهم تعليمة الاسمبلي في صيغة Intel syntax حيث الشكل العام لها :
كود:
operation <destination>, <source>

قيمة المصدر والوجهه ستكون
اما مسجلات او عنوان ذاكرة او قيمة ، والوظائف operations مثل mov و sub و
inc ...لكل منها لها opcode (operation code) مقابل في لغة الآله مثلاً في
الاسفل mov يقابلها ox89 التي تقوم بنقل esp الى ebp ثم طرح 8 من ESP
بواسطة sub .
كود:
8048375:        89 e5                 mov    ebp,esp
8048377:        83 ec 08              sub    esp,0x8

هناك العديد من التعليمات
التي تسيطر على تدفق التنفيذ مثل التعليمة cmp التي تستعمل للمقارنة بين
القيم ، والكثير من التعليمات الاخر مثل تعليمات القفز (فاي تعليمة تبداء
بالحرف j هي تعليمة قفز تعتمد على ناتج المقارنة ومحتوى الريات EFLAGS).
على سبيل المثال المقارنة اسفل بين قيمة الموقع 4-byte ( هنا EBP ناقص
الأزحة 4 ) مع القيمة 9 ، التعليمة التالي قفزة اذا كان الناتج اقل اويساوي
less than or equal من 9 سوف يتحول التنفيذ الى التعليمة على العنوان
0x8048393 ، وغير ذلك سينفذ التعليمة التالي jmp (الغير المشروط) الذي يقفز
الى العنوان 0x80483a6 ، وغالباً هذة التعليمات الثلاث تمثل الشرط
if-then-else control structure في لغة السي.
كود:
804838b:        83 7d fc 09           cmp    DWORD PTR [ebp-4],0x9
804838f:        7e 02                 jle    8048393 <main+0x1f>
8048391:        eb 13                 jmp    80483a6 <main+0x32>

مسجل IP يحتوي على عنوان
التعليمة التالية لكي تنفذ ، وكلاً من النوعين القفز المشروط والغير
المشروط كان القفز الى عنوان متقدم ( قفز أمامي) أو قفز الى عنوان متاخر
(قفز خلفي) يتم حساب IP بواسطة: اضافة IP التعليمة التي تلي القفز مع مقدار
الازاحة الموجبة ، في الخلفي تكون مقدارالازاحة سالبة لذلك عادتاً الازاحة
2’complement على سبيل المثال لو كانت FA هي ازحة بمقدار -6 . بمعنى لحساب
العنوان الجديد يمكن ان نقول :

كود:
IPnew=IPcurrent+displacement

  IPnew=IPcurrent+(2’complement displacement)


في مثال السابق نشاهد قفز
امامي وفي تعليمة jle لديها 7e opcode ومقدار إزاحة 02 وبإضافة IPcurrent
للتعليمة الحالية 8048391 لكي نصل الى العنوان الجديد 8048393 لينتقل
التنفيذ الية. لاننسى ان الاضافة في السادس عشر ويفيدنا حساب IP الجديد الى
أجل لاحق في السيطرة على تنفيذ التعليمات الشرطية والدوال التي تخزن محتوى
مسجل IP على المكدس لكي يعود عنوان العودة الى هذا العنوان(ويتم حساب العنوان الجديد مع التعليمة التي تلي التعليمة call للعودة اليها لاحقاً).
يمكن أستخدام العلام –g مع المجمع لمعرفة معلومات اظافية عند التنقيح .
كود:
[email protected]:~/booksrc $ gcc -g firstprog.c 
[email protected]:~/booksrc $ ls -l a.out
-rwxr-xr-x 1 matrix users 11977 Jul 4 17:29 a.out
[email protected]:~/booksrc $ gdb -q ./a.out
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) list
1       #include <stdio.h>
2
3       int main()
4       {
5               int i;
6               for(i=0; i < 10; i++)
7               {
 8                       printf("Hello, world!\n");
9               }
10      }
(gdb) disassemble main
Dump of assembler code for function main():
0x08048384 <main+0>:    push   ebp
0x08048385 <main+1>:    mov    ebp,esp
0x08048387 <main+3>:    sub    esp,0x8
0x0804838a <main+6>:    and    esp,0xfffffff0
0x0804838d <main+9>:    mov    eax,0x0
0x08048392 <main+14>:   sub    esp,eax 
0x08048394 <main+16>:   mov    DWORD PTR [ebp-4],0x0 
0x0804839b <main+23>:   cmp    DWORD PTR [ebp-4],0x9
0x0804839f <main+27>:   jle    0x80483a3 <main+31>
0x080483a1 <main+29>:   jmp    0x80483b6 <main+50>
0x080483a3 <main+31>:   mov    DWORD PTR [esp],0x80484d4
0x080483aa <main+38>:   call   0x80482a8 <_init+56>
0x080483af <main+43>:   lea    eax,[ebp-4]
0x080483b2 <main+46>:   inc    DWORD PTR [eax]
0x080483b4 <main+48>:   jmp    0x804839b <main+23>
0x080483b6 <main+50>:   leave
0x080483b7 <main+51>:   ret
End of assembler dump.
(gdb) break main
Breakpoint 1 at 0x8048394: file firstprog.c, line 6.
(gdb) run
Starting program: /hacking/a.out

Breakpoint 1, main() at firstprog.c:6
6               for(i=0; i < 10; i++)
(gdb) info register eip
eip            0x8048394        0x8048394
(gdb)

من الملاحظ سابقاً امكانية
مشاهد مصدر الكود مع الامر list ويمكن عمل نقطة توقف على بداية دالة main
فهي تخبر البرنامج بعمل توقف للتنفيذ عند الوصول الى هذة النقطة ، واستخدام
الامر run لتشغيل البرنامج ، نشاهد ايضاً يحتوي EIP على عنوان الذاكرة في
هذة اللحظة الذي يشير الى التعليمات التي تنفذ في الدالة main (مشاهد اعلى
في الخط العريض ) ونلاحظ التعليمات قبل هذا الامر وهي ال function prologue
حيث المجمع يستعملها الى اعدءاد الذكرة للمتغيرات المحلية ثم لعمل لها
rest فيما بعد للدالة .

يمكن لمنقح gdb ان يفحص
الذكرة مباشراً باستعمال المفتاح x وهو اختصار examine ، عندما نفحص في
الذاكرة مع المنقح سوف نشاهد تلك العناوين الموجود في الذاكرة في مختلف
الطرق ، يتوقع هذا الامر اثنين ارجمنت arguments وهما الموقع في الذكرة

للفحص وكيفية عرضة .

تنسيق العرض (يمكن استخدام حرف واحد للإختصار وهنا بعض من هذة format letter :
كود:
o
Display in octal.
x
Display in hexadecimal.
u
Display in unsigned, standard base-10 decimal.
t
Display in binary.

تستخدم تلك مع امر x لفحص
عنوان الذاكرة، وفي المثال التالي العنوان الحالي لمسجل EIP هو المستخدم
حيث يمكن عرض محتوى المسجل EIP في منقح GDB بإستعال i r eip او info
register eip بنفس العمل

كود:
gdb) i r eip
eip            0x8048384        0x8048384 <main+16>
(gdb) x/o 0x8048384
0x8048384 <main+16>:    077042707
(gdb) x/x $eip
0x8048384 <main+16>:    0x00fc45c7
(gdb) x/u $eip
0x8048384 <main+16>:    16532935
(gdb) x/t $eip
0x8048384 <main+16>:    00000000111111000100010111000111
(gdb)

ذاكراة المسجل EIP تحتوي
العنوان 0x8048384 ونلاحظ انة تم فحص هذه الذكراة بواسطة هذا العنوان، يسمح
لنا المنقح بإرجاع المسجلات مباشراً لذلك فهي تكافئ $eip لمحتوى EIP في
نفس الوقت . في المحتوي الموجودة في الذاكرة الرئيسية نجد القيمة 077042707
في الثماني وهي نفسها 0x00fc45c7 في الهكس وفي العشري 16532935 وفي
الثنائي 00000000111111000100010111000111 .

ويمكن وضع عدد يسبقه ( خياري ) وهي عدد العناصر التي تفحص على عنوان الهدف .
كود:
(gdb) x/2x $eip
0x8048384 <main+16>:    0x00fc45c7     0x83000000
(gdb) x/12x $eip
0x8048384 <main+16>:    0x00fc45c7     0x83000000     0x7e09fc7d     0xc713eb02
0x8048394 <main+32>:    0x84842404     0x01e80804     0x8dffffff     0x00fffc45
0x80483a4 <main+48>:    0xc3c9e5eb     0x90909090     0x90909090     0x5de58955
(gdb)

فكما رينا من قبل ان الحجم
الافتراضي هو وحدة فقط والوحدة unit هنا حجمها four-byte وتسمى word ،
ويمكننا تغيرحجم الوحدة وذلك بإضافة حرف من التالي الى نهاية تنسيق العرض :

كود:
A single byte
h
A halfword, which is two bytes in size
w
A word, which is four bytes in size
g
A giant, which is eight bytes in size
 b

ملاحظة :

هناك التشويش في بعض الاوقات
مع مصطلح word في مصطلحات الحواسيب بعض الكتب تقول هي من2-byte وايضاً
double word او DWORD هي من4-byte ، في هذا المقال كلاً من words و DWORDs
هي من 4-byte ، واذا تحدثنا عن 2-byte فأننا نتحدث عن ال short او halfword
خرج المنقح في مختلف الاحجام :

كود:
(gdb) x/8xb $eip
0x8048384 <main+16>:    0xc7    0x45    0xfc    0x00    0x00    0x00    0x00    0x83
(gdb) x/8xh $eip
0x8048384 <main+16>:    0x45c7  0x00fc  0x0000  0x8300  0xfc7d  0x7e09  0xeb02  0xc713
(gdb) x/8xw $eip
0x8048384 <main+16>:    0x00fc45c7      0x83000000      0x7e09fc7d      0xc713eb02
0x8048394 <main+32>:    0x84842404      0x01e80804      0x8dffffff      0x00fffc45 
(gdb)

واذا نظرت بقرب سنلاحظ بعض
الاشياء عن البيانات فوق ، كما نشاهد في اوامر الفحص تستعمل وحدادات عرض
اكبر واكثر بيانات في المجموع مع كل وحدة ، في اول فحص نراه من لأوال اثنين
بايت 0xc7 و 0x45 ولكن عند ثاني فحص مع halfword نجد مع الفحص على نفس
عناوين الذاكرة اصبح 0x45c7 التي هي معكوسة البايت ، والتي تعمل نفس
التأثير مع four-byte word كما هو مشاهد 0x00fc45c7 التي هي مشاهدة في اول
فحص عندما كانت 0xc7, 0x45, 0xfc, 0x00. .

وهذا بسبب ان القيم تخزن على
المعالجات x86 في طلب little-endian byte ، والتي تعني ان ال least
significant byte هو من يخزن اولاً فهذة العملية تسعمل من قبل المجمعات
وكذلك المنقح لطلب البايت حيث تقوم بعكس البايت ولكي نتأكد من طلب البايت
نسعمل بعض الحسابات
كود:
(gdb) x/4xb $eip
0x8048384 <main+16>:    0xc7    0x45    0xfc    0x00
(gdb) x/4ub $eip
0x8048384 <main+16>:    199     69      252     0
(gdb) x/1xw $eip
0x8048384 <main+16>:    0x00fc45c7
(gdb) x/1uw $eip
0x8048384 <main+16>:    16532935
(gdb) quit
The program is running.  Exit anyway? (y or n) y
[email protected]:~/booksrc $ bc -ql
199*(256^3) + 69*(256^2) + 252*(256^1) + 0*(256^0)
3343252480
0*(256^3) + 252*(256^2) + 69*(256^1) + 199*(256^0)
16532935
quit
[email protected]:~/booksrc $

فاولأ عرض اربعة بايت للمسجل
eip في الهكس وفي الاعداد العشرية الموجبة ، وبعد الخروج من المنقح استخدمت
الحاسبة bc للتأكد من القيمة الصحيحة لطلب البايت المستخدم في الحاسوب .
بالاظافة فقد راينا عملية
disassemble لفك تعليمات لغة الآله الى الاسمبلي ، ايضاً يمكننا فحص
باستعمال امر الفحص x مع الحرف i وهو اختصار instruction لعرض الذكراة كال
disassemble :
كود:
[email protected]:~/booksrc $ gdb -q ./a.out
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) break main
Breakpoint 1 at 0x8048384: file firstprog.c, line 6.
(gdb) run
Starting program: /home/reader/booksrc/a.out

Breakpoint 1, main () at firstprog.c:6 
6         for(i=0; i < 10; i++)
(gdb) i r $eip
eip            0x8048384        0x8048384 <main+16>
(gdb) x/i $eip
0x8048384 <main+16>:    mov    DWORD PTR [ebp-4],0x0
(gdb) x/3i $eip
0x8048384 <main+16>:    mov    DWORD PTR [ebp-4],0x0
0x804838b <main+23>:    cmp    DWORD PTR [ebp-4],0x9
0x804838f <main+27>:    jle    0x8048393 <main+31>
(gdb) x/7xb $eip
0x8048384 <main+16>:    0xc7    0x45    0xfc    0x00    0x00    0x00    0x00
(gdb) x/i $eip
0x8048384 <main+16>:    mov    DWORD PTR [ebp-4],0x0
(gdb)

لان مسجل EIP يشير الى موقع
الذاكرة الرئيسية الذي يحتوي على البيانات وتعليمات لغة الآله يمكن عمل لها
فك واعرابها الى لغة الاسملبي كما هو ملاحظ عند اخر عمليتين التي تثبت
سبعة بايت للمسجل EIP .وفي التحليل السابق مع اداة objdump عند عمل
disassembly ( كما هو مشاهد في الاسفل ) السبعة البايتات لمسجل EIP تشير
الى تعليمات لغة الآله لتعليمات المقابل له في الاسمبلي .
كود:
8048384:      c7 45 fc 00 00 00 00   mov   DWORD PTR [ebp-4],0x0
ذة التعليمة لنقل القيمة 0
الى موقع الذاكرة على العنوان المخزن في مسجل EBP ناقص 4 ، وذلك لان متغير i
في البرنامج يخزن في الذاكرة ويعلن عنه كعدد صحيح integer ويستعمل 4 بايت
من الذاكرة على معالجات x86 ، فالقيمة الابتدائية له ستكون بصفر خارج
التكرار for .

فاذا فحصت الذاكرة في هذة اللحظه سوف تحتوي على قيم عشوائية ، والذاكرة على هذا الموقع يمكن ان تفحص بعده طرق :
كود:
(gdb) i r ebp
ebp            0xbffff808       0xbffff808
(gdb) x/4xb $ebp - 4
0xbffff804:     0xc0    0x83    0x04    0x08
(gdb) x/4xb 0xbffff804
0xbffff804:     0xc0    0x83    0x04    0x08
(gdb) print $ebp - 4
$1 = (void *) 0xbffff804
(gdb) x/4xb $1
0xbffff804:     0xc0    0x83    0x04    0x08
(gdb) x/xw $1
0xbffff804:     0x080483c0
(gdb

المسجل EBP يحتوي على العنوان
0xbffff808 ،ثم يكتب قيمة offset التي هي اقل من العنوان 0xbffff804
بأربعة في المكدس ، يمكن ان نفحص هذا العنوان كما سبق بالامر x ، ثم بالامر
print الناتج يخزن في متغير $1 في المنقح ويمكن ان يستعمل للوصول الى هذا
الموقع من الذاكرة فيما بعد

يمكن تنفيذ التعليمة الحالية
والتقدم خطوة الى الامام بإستخدام الامر nexti اختصار next instruction ،
حيث يعمل المعالج على قراءة التعليمة على EIP وينفذها وتقديم EIP الى
التعليمة التالية .
كود:
(gdb) nexti
0x0804838b      6        for(i=0; i < 10; i++)
(gdb) x/4xb $1
0xbffff804:     0x00   0x00    0x00    0x00
(gdb) x/dw $1
0xbffff804:     0
(gdb) i r eip
eip            0x804838b       0x804838b <main+23>
(gdb) x/i $eip
0x804838b <main+23>:    cmp   DWORD PTR [ebp-4],0x9
(gdb)

كما هو متوقع في الامر السابق وضعت القيمة صفر على المسجل EBP- 4 التي توضع لمتغير السي (i) في الذاكرة ، ثم تقديم EIP الى التعليمة التالية . الان سوف نفحص بعض من تعليمات البرنامج
كود:
(gdb) x/10i $eip
0x804838b <ma in+23>:   cmp   DWORD PTR [ebp-4],0x9
0x804838f <main+27>:   jle   0x8048393 <main+31>
0x8048391 <main+29>:   jmp   0x80483a6 <main+50>
0x8048393 <main+31>:   mov   DWORD PTR [esp],0x8048484 
0x804839a <main+38>:   call  0x80482a0 <[email protected]>
0x804839f <main+43>:   lea   eax,[ebp-4]
0x80483a2 <main+46>:   inc   DWORD PTR [eax]
0x80483a4 <main+48>:   jmp   0x804838b <main+23>
0x80483a6 <main+50>:   leave 
0x80483a7 <main+51>:   ret
(gdb)

القيمة صفر المخزنة في موقع الذاكرة في البرنامج اقل من القيمة 9 لذلك EIP يجب ان يحوي على 0x8048393 بعد تنفيذ التعلمتين التالية :
كود:
(gdb) nexti
0x0804838f      6          for(i=0; i < 10; i++)
(gdb) x/i $eip
0x804838f <main+27>:     jle    0x8048393 <main+31>
(gdb) nexti
8            printf("Hello, world!\n");
(gdb) i r eip
eip            0x8048393        0x8048393 <main+31>
(gdb) x/2i $eip
0x8048393 <main+31>:    mov    DWORD PTR [esp],0x8048484
0x804839a <main+38>:    call   0x80482a0 <[email protected]>
(gdb)

كما توقعنا في البداية يبدأ تدفق التفيذ الى 0x8048393 بعد التقديم الى التعليمتين. فأول تعليمة هي mov التي تضع عنوان 0x8048484 الى محتوى عنوان الذاكرة الذي يشير إلية ESP ، ولمعرفة ما يشير الية ESP نقوم بما يلي :
كود:
(gdb) i r esp
    esp           0xbffff800       0xbffff800
    (gdb)

حالياً يشير ESP الى عنوان الذاكرة 0xbffff800 لذا عندما التعليمة mov تنفذ يكتب العنوان 0x8048484 الى ذلك العنوان . الشيء الاخر لنفحص عنوان الذاكرة 0x8048484 ماالذي يحتوي
كود:
(gdb) x/2xw 0x8048484
    0x8048484:      0x6c6c6548      0x6f57206f
    (gdb) x/6xb 0x8048484
    0x8048484:      0x48    0x65    0x6c   0x6c   0x6f   0x20
    (gdb) x/6ub 0x8048484
    0x8048484:      72      101     108    108    111 32
    (gdb)

البايت 0x48, 0x65, 0x6c, and 0x6f ليست كانماط مرئية فهي من ضمن ASCII أي كل بايت مايقابلة حرف في جدول ASCII وهنا بكتابة الامر man ascii على الشل للحصول على الجدول :
كود:
ASCII Table


كود:
Oct   Dec   Hex   Char           Oct   Dec   Hex   Char 
    ------------------------------------------------------------
    000   0     00    NUL '\0'       100   64    40    @
    001   1     01    SOH            101   65    41    A
    002   2     02    STX            102   66    42    B
    003   3     03    ETX            103   67    43    C
    004   4     04    EOT            104   68    44    D
    005   5     05    ENQ            105   69    45    E
    006   6     06    ACK            106   70    46    F
    007   7     07    BEL '\a'       107   71    47    G
    010   8     08    BS  '\b'       110   72    48    H
    011   9     09    HT  '\t'       111   73    49    I
    012   10    0A    LF  '\n'       112   74    4A    J
    013   11    0B    VT  '\v'       113   75    4B    K
    014   12    0C    FF  '\f'       114   76    4C    L
    015   13    0D    CR  '\r'       115   77    4D    M
    016   14    0E    SO             116   78    4E    N
    017   15    0F    SI             117   79    4F    O
    020   16    10    DLE            120   80    50    P
    021   17    11    DC1            121   81    51    Q
    022   18    12    DC2            122   82    52    R
    023   19    13    DC3            123   83    53    S
    024   20    14    DC4            124   84    54    T
    025   21    15    NAK            125   85    55    U
    026   22    16    SYN            126   86    56    V
    027   23    17    ETB            127   87    57    W
    030   24    18    CAN            130   88    58    X
    031   25    19    EM             131   89    59    Y
    032   26    1A    SUB            132   90    5A    Z
    033   27    1B    ESC            133   91    5B    [
    034   28    1C    FS             134   92    5C    \   '\\'
    035   29    1D    GS             135   93    5D    ]
    036   30    1E    RS             136   94    5E    ^
    037   31    1F    US             137   95    5F    _
    040   32    20    SPACE          140   96    60    `
    041   33    21    !              141   97    61    a
    042   34    22    "              142   98    62    b
    043   35    23    #              143   99    63    c
    044   36    24    $              144   100   64    d
    045   37    25    %              145   101   65    e
    046   38    26    &              146   102   66    f
    047   39    27    '              147   103   67    g
    050   40    28    (              150   104   68    h
    051   41    29    )              151   105   69    i
    052   42    2A    *              152   106   6A    j
    053   43    2B    +              153   107   6B    k
    054   44    2C    ,              154  108   6C     l
    055   45    2D    -              155   109   6D    m
    056   46    2E    .              156   110   6E    n
    057   47    2F    /              157  111   6F    o
    060   48    30    0              160   112   70    p
    061   49    31    1              161   113   71    q
    062   50    32    2              162   114   72    r
    063   51    33    3              163   115   73    s
    064   52    34    4              164   116   74    t
    065   53    35    5              165   117   75    u
    066   54    36    6              166   118   76    v
    067   55    37    7              167   119   77    w
    070   56    38    8              170   120   78    x
    071   57    39    9              171   121   79    y
    072   58    3A    :              172   122   7A    z
    073   59    3B    ;              173   123   7B    {
    074   60    3C    <              174   124   7C    |
    075   61    3D    =              175   125   7D    }
    076   62    3E    >              176   126   7E    ~
    077   63    3F    ?              177   127   7F    DEL

لكن يوفر GDB لنا لأمر الفحص لإستعمال لمثل هذا النوع كال (c) format letter لنظر مباشرتاً على البايت على جدول ASCII ، و(s) format letter لعرض سلاسلة البيانات كاملة :
كود:
(gdb) x/6cb 0x8048484
0x8048484:      72 'H'  101 'e' 108 'l' 108 'l' 111 'o' 32 ' '
(gdb) x/s 0x8048484
0x8048484:       "Hello, world!\n"
(gdb)

يظهر الأوامر بأن سلاسلة البيانات "Hello, world!\n" مخزنة على عنوان الذاكرة 0x8048484 ،وتعد الدالة printf() لإستقبال عنوان هذة السلالة الى ESP (0x8048484) لان الدالة printf() معده لهذا العمل .ونشاهد في الخرج التالي لعنوان سلاسلة البيانات ينقل الى عنوان ESP ليشير اليه
كود:
(gdb) x/2i $eip
0x8048393 <main+31>:    mov    DWORD PTR [esp],0x8048484
0x804839a <main+38>:    call   0x80482a0 <[email protected]>
(gdb) x/xw $esp
0xbffff800:     0xb8000ce0
(gdb) nexti
0x0804839a      8           printf("Hello, world!\n");
(gdb) x/xw $esp
0xbffff800:     0x08048484 
(gdb)

التعليمة التالي تستدعى الدالة printf() لطباعة سلاسل البيانات ، والتعليمة السابقة يتم اعداءها لإستدعى الدالة والنتيجة من استدعى الدالة تظهر في الخرج اسفل كما هو مشاهد في خط عريض
كود:
(gdb) x/i $eip
0x804839a <main+38>:    call   0x80482a0 <[email protected]>
(gdb) nexti
Hello, world!
6         for(i=0; i < 10; i++)
(gdb)

نستمر في التنقيح ونفحص تعليمتين تالية مرة اخرى سوف يبدو الخرج مثل هذا
كود:
(gdb) x/2i $eip
0x804839f <main+43>:    lea    eax,[ebp-4]
0x80483a2 <main+46>:    inc    DWORD PTR [eax]
(gdb)

تعليمة inc لزيادة قيمة المتغير i بواحد ، التعليمة lea اختصار Load Effective Address لشحن العنوان المماثل ل EBP - 4 الى مسجل EAX . لنرى اسفل تنفيذ هذة التعليمة
كود:
(gdb) x/i $eip
0x804839f <main+43>:    lea    eax,[ebp-4]
(gdb) print $ebp - 4
$2 = (void *) 0xbffff804
(gdb) x/x $2
0xbffff804:     0x00000000
(gdb) i r eax
eax            0xd      13
(gdb) nexti
0x080483a2      6         for(i=0; i < 10; i++)
(gdb) i r eax
eax            0xbffff804       -1073743868
(gdb) x/xw $eax
0xbffff804:     0x00000000
(gdb) x/dw $eax
0xbffff804:     0
(gdb)

التعليمة التالية inc زيادة قيمة المتغير الموجود على هذا العنوان (حالياً مخزن في مسجل EAX ) بواحد .وبعد تنفيذ هذة التعليمة
كود:
gdb) x/i $eip
0x80483a2 <main+46>:    inc    DWORD PTR [eax]
(gdb) x/dw $eax
0xbffff804:     0
(gdb) nexti
0x080483a4      6         for(i=0; i < 10; i++)
(gdb) x/dw $eax
0xbffff804:     1
(gdb)

قيمة المتغير تخزن على موقع ذاكرة EBP - 4 الذي ايضاً يشير الية المسجل eax ، التعليمة التالية للقفز الغير مشروط :
كود:
(gdb) x/i $eip
0x80483a4 <main+48>:    jmp    0x804838b <main+23> 
(gdb)

عندما هذة التعليمة تنفذ ،
سوف يرسل البرنامج عاداً الى التعليمة على العنوان 0x804838b. فهي ببساطة
توضع EIP الى تلك القيمة . يستمر تنفذ الدالة printf() وتزتاد قيمة المتغير
طالما لم يصل القيمة 10 ، والا لان يتم تنفذ التعليمة jle ويستمر
instruction pointer الى تعليمة القفز الغير مشروط لإنهاء الحلقة والبرنامج
كود:
(gdb) disass main
Dump of assembler code for function main:
0x08048374 <main+0>:    push   ebp
0x08048375 <main+1>:    mov    ebp,esp
0x08048377 <main+3>:    sub    esp,0x8
0x0804837a <main+6>:    and    esp,0xfffffff0
0x0804837d <main+9>:    mov    eax,0x0
0x08048382 <main+14>:   sub    esp,eax
0x08048384 <main+16>:   mov    DWORD PTR [ebp-4],0x0
0x0804838b <main+23>:   cmp    DWORD PTR [ebp-4],0x9
0x0804838f <main+27>:   jle    0x8048393 <main+31>
0x08048391 <main+29>:   jmp    0x80483a6 <main+50> 
0x08048393 <main+31>:   mov    DWORD PTR [esp],0x8048484
0x0804839a <main+38>:   call   0x80482a0 <[email protected]> 
0x0804839f <main+43>:   lea    eax,[ebp-4]
0x080483a2 <main+46>:   inc    DWORD PTR [eax]
0x080483a4 <main+48>:   jmp    0x804838b <main+23> 
0x080483a6 <main+50>:   leave
0x080483a7 <main+51>:   ret
End of assembler dump.
(gdb) list
1       #include <stdio.h>
2
3       int main()
4       {
5         int i;
6         for(i=0; i < 10; i++)
7         { 
8           printf("Hello, world!\n"); 
9         } 
10      } 
(gdb)

التعليمات المبينة في جعل جزيئة فى الحلقة ، وهنا المتغير printf () داخل الحلقة. تنفيذ البرنامج سوف يقفز مرة أخرى إلى المقارنة بين التعليم ، ومواصلة لتنفيذ لبمتغير printf () ، وزيادة المتغير العداد حتى النهاية يساوي 10. عند هذه النقطة التعليمة الشرطية jle = عدم التنفيذ ، بدلا من ذلك ، مؤشر التعليمة ستواصل التعليمة قفزة غير المشروط ، الذي يخرج من حلقة وينتهي البرنامج.

إنتها البرنامج وسوف أنهي درسي معاه لاني تعبت
بتوفيق للجميع
أخكم
RaYm0n

توقيع
.::TeaM HITMAN HaCkEr::.
قل نعم أستطيع بإذن الله
http://www.h-online.com/security/img...44de77efee.png
3 أعضاء قالوا شكراً لـ RaYm0n على المشاركة المفيدة:
02-09-2010, 06:58 PM
Ma3sTr0-Dz :: Sec4ever#TG ::
  • شكراً: 817
  • تم شكره 366 مرة في 106 مشاركة

بارك لله فيك خويا ياسين شرح متعوب عليه ، بعد الافطار اركز معاه واسألك .

توقيع
One Team , One Love , One Heart
Sec4ever
02-09-2010, 07:01 PM
RaYm0n TeaM HITMAN HaCkEr
TeaM A
  • شكراً: 9
  • تم شكره 377 مرة في 115 مشاركة

المشاركة الأصلية كتبت بواسطة Ma3sTr0-Dz اقتباس :
بارك لله فيك خويا ياسين شرح متعوب عليه ، بعد الافطار اركز معاه واسألك .
انا هنا معندي فين نهرب

توقيع
.::TeaM HITMAN HaCkEr::.
قل نعم أستطيع بإذن الله
http://www.h-online.com/security/img...44de77efee.png
08-09-2010, 12:29 PM
G705T H4CK3r عضو مميز
TeaM C
  • شكراً: 9
  • تم شكره 41 مرة في 12 مشاركة

شررح متعوب عليه جاري المراجعة كوني اريد تعلم الهندسة العكسية

08-09-2010, 02:39 PM
RaYm0n TeaM HITMAN HaCkEr
TeaM A
  • شكراً: 9
  • تم شكره 377 مرة في 115 مشاركة

المشاركة الأصلية كتبت بواسطة G705T H4CK3r اقتباس :
شررح متعوب عليه جاري المراجعة كوني اريد تعلم الهندسة العكسية
بتوفيق أخي

توقيع
.::TeaM HITMAN HaCkEr::.
قل نعم أستطيع بإذن الله
http://www.h-online.com/security/img...44de77efee.png
08-09-2010, 03:03 PM
BlaCK CobRa عضو مميز
  • شكراً: 26
  • تم شكره 15 مرة في 10 مشاركة

يعطيك العافية رايمون

درس دسم صراحة رح اتابعه بعد الفطور

سؤال : هل هذه الصفحة كلها من كتابة يدك ؟

Own3r عضو جديد
  • شكراً: 0
  • تم شكره 0 مرة في 0 مشاركة

الله يعطيك العافية اخوي
درس كبير مثل كاتبه
شكر على مجهود المتعوب عليه
بارك الله فيك

RaYm0n TeaM HITMAN HaCkEr
TeaM A
  • شكراً: 9
  • تم شكره 377 مرة في 115 مشاركة

أهلا بكم إخواني

هادي الصفحة اخدت مني 4 سعات

توقيع
.::TeaM HITMAN HaCkEr::.
قل نعم أستطيع بإذن الله
http://www.h-online.com/security/img...44de77efee.png
HdZ61 عضو مميز
  • شكراً: 223
  • تم شكره 64 مرة في 30 مشاركة

الله يبارك فيك خيوووووو مشكوررررررر

توقيع
abdellatef
TeaM B
  • شكراً: 648
  • تم شكره 240 مرة في 69 مشاركة

الله احفظك خويا والتنقيح لابد من برنامج onlydbg باش تسهل القضية علك شوي
الله يحفظك تم حفظ الشرح لللمراجعة رايته طويل والف شكر لك جد متعوب عليه الله يعزيك