דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
  1. דף הבית
  2. מחשבים וטכנולוגיה
  3. עזרה הדדית - מחשבים וטכנולוגיה
  4. שיתוף | יכול להיות שבניתי את התוכנה הכי קטנה בעולם?

שיתוף | יכול להיות שבניתי את התוכנה הכי קטנה בעולם?

מתוזמן נעוץ נעול הועבר עזרה הדדית - מחשבים וטכנולוגיה
25 פוסטים 11 כותבים 655 צפיות 11 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • מתכנת חובבמ מתכנת חובב

    @אלישע-מואב-0 @אביגדור-ברמן מתברר שדרסתי בטעות את ה data dirctory ומכיוון שזה קובץ קצת מוזר ווינדוס ניסה לתקן אותו בריצה הראשונה דרך קובץ dll שנקרא apphelp וספציפית בפונקציה SepRouterHookIAT שמשמשת כ hook לקריאה חיצונית של ה IAT ומכיוון שכתבתי עליו טקסט (הכותרת של החלון) שבקריאה שלו ככתובת יוצא כתובת של זיכרון רחוק שלא הוקצה קופצת שגיאת access violation בפעם הראשונה
    בדרך כלל אחרי הקריסה הראשונה ווינדוס מסמן את הקובץ כקובץ שאין עניין לתקן והקובץ רץ
    אפשר לנסות להגדיר Size Of Image לערך עצום שאולי יכלול בתוכו את אותה כתובת אבל אז זה עלול ליפול שם
    בקיצור מה שעשיתי זה לאפס את השדה של הגודל של אותה כניסת IAT וכך ווינדוס לא מנסה לטעון אותה אבל זה עלה לי במחיר צמצום הכותרת
    החלפתי את הקובץ לעיל בקובץ מתוקן

    בנימין מחשביםב מנותק
    בנימין מחשביםב מנותק
    בנימין מחשבים
    כתב נערך לאחרונה על ידי בנימין מחשבים
    #12

    @מתכנת-חובב עדיין אותה שגיאה. (גם לאחר הפעלות חוזרות ונשנות)

    7917ca3f-d9b6-4cb0-ad9a-b7816dc5f1a1-image.png

    מתכנת חובבמ תגובה 1 תגובה אחרונה
    1
    • בנימין מחשביםב בנימין מחשבים

      @מתכנת-חובב עדיין אותה שגיאה. (גם לאחר הפעלות חוזרות ונשנות)

      7917ca3f-d9b6-4cb0-ad9a-b7816dc5f1a1-image.png

      מתכנת חובבמ מנותק
      מתכנת חובבמ מנותק
      מתכנת חובב
      מדריכים
      כתב נערך לאחרונה על ידי
      #13

      @בנימין-מחשבים מעניין בארבעה מחשבים שבדקתי זה היה בסדר
      אשמח אם יש עוד מישהו שיוכל לבדוק ולעדכן

      צריך עזרה בשחזור מידע? ייעוץ? egozkokus1@gmail.com

      תגובה 1 תגובה אחרונה
      0
      • יאיר דניאלי מנותק
        יאיר דניאלי מנותק
        יאיר דניאל
        כתב נערך לאחרונה על ידי יאיר דניאל
        #14

        לא עובד לי
        cc637373-713d-4fa4-9727-09578a80bc28-image.png

        עריכה: זה היה רק במחשב מסויים - במחשב שלי עובד מצויין

        מתכנת חובבמ תגובה 1 תגובה אחרונה
        0
        • יאיר דניאלי יאיר דניאל

          לא עובד לי
          cc637373-713d-4fa4-9727-09578a80bc28-image.png

          עריכה: זה היה רק במחשב מסויים - במחשב שלי עובד מצויין

          מתכנת חובבמ מנותק
          מתכנת חובבמ מנותק
          מתכנת חובב
          מדריכים
          כתב נערך לאחרונה על ידי
          #15

          @יאיר-דניאל אני בודק את זה
          אולי מדובר ב build לא תואם אבל מעניין

          צריך עזרה בשחזור מידע? ייעוץ? egozkokus1@gmail.com

          1 תגובה 1 תגובה אחרונה
          1
          • מתכנת חובבמ מתכנת חובב

            @יאיר-דניאל אני בודק את זה
            אולי מדובר ב build לא תואם אבל מעניין

            1 מנותק
            1 מנותק
            106
            כתב נערך לאחרונה על ידי
            #16

            @מתכנת-חובב עבד להפליא כבר בפעם הראשונה
            9f925f36-8e77-4985-8bf9-a91ca50da3a4-תמונה.png

            מתכנת חובבמ תגובה 1 תגובה אחרונה
            0
            • ה מנותק
              ה מנותק
              המלאך
              כתב נערך לאחרונה על ידי
              #17

              @מתכנת-חובב מאוד יפה!
              אהבתי את הרעיון.

              תגובה 1 תגובה אחרונה
              0
              • 1 106

                @מתכנת-חובב עבד להפליא כבר בפעם הראשונה
                9f925f36-8e77-4985-8bf9-a91ca50da3a4-תמונה.png

                מתכנת חובבמ מנותק
                מתכנת חובבמ מנותק
                מתכנת חובב
                מדריכים
                כתב נערך לאחרונה על ידי
                #18

                @106 עבדתי מאוד קשה כדי שיעבוד בפעם הראשונה...
                תכלס יש מחשבים שזה נפל בהם בגלל שווינדוס לפעמים קצת חצוף (אולי מחר אני יכתוב הסבר מסודר על תהליך הבניה)
                אבל עבדתי קשה והצלחתי
                עכשיו יש גרסה שבעזרת השם תעבוד אצל כולם

                צריך עזרה בשחזור מידע? ייעוץ? egozkokus1@gmail.com

                תגובה 1 תגובה אחרונה
                7
                • מתכנת חובבמ מתכנת חובב

                  נחשפתי לאחרונה לעולם של התוכנות הזעירות - אמנות שבה דוחסים שדות בקובץ exe אחד על השני ומצמצמים את הקוד עצמו למינימום ו"עובדים" על ה loader של ווינדוס כמה שאפשר
                  הגודל המינימלי של התוכנות האלו נכון להיום הוא 268 בתים בגלל דרישות יישור ולכאורה מבנה ה struct שה loader של ווינדוס מחפש לקרוא כשהוא פותח קובץ
                  הקבצים שראיתי ברשת (האמת שלא חקרתי הרבה) - כל מה שהם עושים היה סך הכל לבצע return ל loader או סתם להגדיר ערך כלשהו ב EAX אבל לא באמת משהו מעניין
                  אז ישבתי להכין תוכנת hello world שתשב באותו גודל מינימלי והצלחתי אפילו יותר - יש לי 2 בתים ריקים בסוף שהשארתי שם 00 בשביל הריפוד לגודל הנדרש ככה שסך כל הגודל של התוכנה הוא 266 בתים!
                  הבניה של זה הייתה די מסובכת ולקחה לי כמה שעות של מלחמות עם ווינדוס ואסמבלי ובשלב מסויים גם עם הבינארי עצמו (וגיליתי שלא כזה מסובך לעשות patching ידני ל opcodes)
                  ממה שבדקתי זאת תוכנת ה hello world הכי קטנה בעולם אבל אולי יש משהו שמנצל אפילו פחות או עושה דברים נוספים (ניסיתי לגרום לו גם לצפצף אבל זה דרש כבר שכתוב של כל ה opcodes וסדר הריצה ואין לי זמן \ כוח לזה עכשיו אבל זה נראה אפשרי) - אם מישהו ימצא משהו טוב יותר אשמח אם הוא יוכל ליידע אותי
                  אם מעניינים פרטים טכניים על הקובץ והבניה שלו - תוכלו לבקש ואשמח לשתף
                  בדקתי את הקובץ אצלי - גרסת build 26200.7840 אבל יכול להיות שבעדכוני ווינדוס הבאים זה יישבר
                  מצורף הקובץ וה dump שלו למי שמתעניין
                  smallest_hello_world.exe

                  עריכה: אחרי ששמעתי ממשתמשים שהתוכנה קרסה אצלם מתברר שיש גרסאות של ווינדוס שבהם מתבצעות בדיקות שונות ולעשות תוכנה אחת שתעבוד אצל כולם זה חתיכת סיפור
                  אחרי שסידרתי את עניין ה IAT קפץ עלי רוגזה של בדיקת DRM בגלל דגל debugging לא מאופס (הוא נופל אצלי בדיוק באמצע הקוד...) מקווה שאצליח לסדר את זה
                  עריכה: סודר
                  אם קורס אצלכם אשמח שתודיעו לי

                  4D 5A 00 00 50 45 00 00 4C 01 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 00 00 02 01 0B 01 FF FF FF FF FF 75 73 65 72 33 32 00 00 FF 88 00 00 00 6D 69 74 6D 2E 74 6F 70 00 00 40 00 04 00 00 00 04 00 00 00 06 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 0C 01 00 00 6F 00 00 00 00 00 00 00 02 00 00 00 00 00 10 00 00 10 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 BF A8 A2 4D BC EB 31 00 00 00 00 00 64 A1 30 00 00 00 8B 40 0C 8B 40 14 8B 00 8B 00 8B 68 10 BF 8E 4E 0E EC E8 23 00 00 00 68 23 00 40 00 FF D0 95 EB CD 90 00 00 00 00 E8 11 00 00 00 6A 00 68 30 00 40 00 68 0C 00 40 00 6A 00 FF D0 C3 8B 55 3C 8B 54 15 78 01 EA 8B 4A 18 8B 5A 20 01 EB 49 8B 34 8B 01 EE 52 31 C0 99 AC 84 C0 74 07 C1 CA 0D 01 C2 EB F4 39 FA 5A 75 E5 8B 5A 24 01 EB 0F B7 0C 4B 8B 5A 1C 01 EB 03 2C 8B 89 E8 C3 00 00
                  

                  c2bdc5e4-1e9f-4048-b739-ce3a04c47cbf-image.png

                  עריכה: יצאה גרסה מעודכנת וסופית
                  https://mitmachim.top/topic/93863/שיתוף-התוכנה-הכי-קטנה-בעולם-עכשיו-גם-מנגנת

                  א מנותק
                  א מנותק
                  אביגדור ברמן
                  כתב נערך לאחרונה על ידי
                  #19

                  @מתכנת-חובב
                  בבתים ששלחת:
                  6D 69 74 6D 2E 74 6F 70 מתרגם ל-mitm.top. ! ! !

                  זה מופיע מיד אחרי המחרוזת hello world!, מה שמחזק את ההשערה שמדובר בתוכנית דוגמה קטנה שנכתבה על ידי אחד מחברי הקהילה שם כדי להדגים יכולות תכנות ב-Assembly או מניפולציה של קבצי EXE.

                  מתכנת חובבמ תגובה 1 תגובה אחרונה
                  1
                  • א אביגדור ברמן

                    @מתכנת-חובב
                    בבתים ששלחת:
                    6D 69 74 6D 2E 74 6F 70 מתרגם ל-mitm.top. ! ! !

                    זה מופיע מיד אחרי המחרוזת hello world!, מה שמחזק את ההשערה שמדובר בתוכנית דוגמה קטנה שנכתבה על ידי אחד מחברי הקהילה שם כדי להדגים יכולות תכנות ב-Assembly או מניפולציה של קבצי EXE.

                    מתכנת חובבמ מנותק
                    מתכנת חובבמ מנותק
                    מתכנת חובב
                    מדריכים
                    כתב נערך לאחרונה על ידי
                    #20

                    @אביגדור-ברמן מה אתה בא לומר?
                    די ברור שזה מה שרציתי לעשות

                    צריך עזרה בשחזור מידע? ייעוץ? egozkokus1@gmail.com

                    א תגובה 1 תגובה אחרונה
                    1
                    • מתכנת חובבמ מתכנת חובב

                      @אביגדור-ברמן מה אתה בא לומר?
                      די ברור שזה מה שרציתי לעשות

                      א מנותק
                      א מנותק
                      אביגדור ברמן
                      כתב נערך לאחרונה על ידי
                      #21

                      @מתכנת-חובב זה מגניב!
                      (אני לא מבין בזה, זה הגברת בינה...)

                      תגובה 1 תגובה אחרונה
                      1
                      • cfopuserC מנותק
                        cfopuserC מנותק
                        cfopuser
                        כתב נערך לאחרונה על ידי
                        #22

                        מרשים מאוד.

                        534c21b3-7f7c-4809-b995-e17e8c026e30-image.png

                        תגובה 1 תגובה אחרונה
                        1
                        • iosi poliI מנותק
                          iosi poliI מנותק
                          iosi poli
                          כתב נערך לאחרונה על ידי
                          #23

                          עבד בפעם הראשונה 🙂
                          מאסטר האסמבלי..

                          אם טעיתי, בבקשה תתקן אותי!

                          תגובה 1 תגובה אחרונה
                          1
                          • מתכנת חובבמ מתכנת חובב התייחס לנושא זה
                          • א מנותק
                            א מנותק
                            אביגדור ברמן
                            כתב נערך לאחרונה על ידי אביגדור ברמן
                            #24

                            גיפיטי מסביר מה הולך שם בבינארי - בספויילר

                            הסבר טכני תמציתי, שלב-אחר-שלב, למה שהקובץ עושה בפועל:

                            1. טעינה ע״י ה-Loader

                            תחילת הקובץ מכילה חתימות MZ ו-PE\0\0.

                            ה-Loader של Windows מזהה זאת כ-PE, ממפה את ה-Image לזיכרון לפי ה-headers ומקפיץ ל-EntryPoint.

                            1. אין Import Table רגילה

                            ה-DataDirectory של Imports ריק/לא בשימוש.

                            לכן אין IAT סטטית.

                            במקום זאת הקוד פותר APIs בזמן ריצה (manual resolving).

                            1. קבלת כתובת בסיס של מודולים (גישה ל-PEB)

                            ב-EntryPoint מתבצעת גישה ל-PEB דרך ה-segment register (ב-x86 דרך ‎FS:[0x30]‎).

                            מהלך טיפוסי:

                            קריאה ל-PEB

                            כניסה ל-PEB_LDR_DATA

                            מעבר על רשימת InMemoryOrderModuleList

                            כך מאתרים את:

                            ‎kernel32.dll‎ (כבר טעון בתהליך)

                            1. מציאת Export Table של kernel32

                            לאחר שיש BaseAddress של kernel32:

                            קריאת offset ‎e_lfanew‎ מתוך DOS header

                            קפיצה ל-NT Headers

                            גישה ל-DataDirectory → Export Table

                            חישוב כתובות:

                            AddressOfNames

                            AddressOfFunctions

                            AddressOfNameOrdinals

                            1. לולאת Hash על שמות פונקציות

                            הקוד עובר על כל שם פונקציה ב-Export Table:

                            מבנה אופייני שנראה אצלך:

                            AC
                            84 C0
                            74 07
                            C1 CA 0D
                            01 C2

                            זו לולאה שמבצעת:

                            קריאה תו-תו

                            rotate right

                            הוספת ערך

                            יצירת hash

                            כאשר ה-hash תואם לערך קשיח שמקודד בקוד → נמצאה הפונקציה.

                            בדרך זו מאתרים:

                            LoadLibraryA

                            GetProcAddress

                            1. טעינת user32.dll

                            אחרי שיש כתובת של LoadLibraryA:

                            הקוד קורא לה עם המחרוזת "user32"

                            מתקבלת כתובת בסיס של user32.dll

                            1. מציאת MessageBoxA

                            שוב מתבצע:

                            סריקת Export Table של user32

                            חישוב hash

                            התאמה ל-MessageBoxA

                            קבלת ה-function pointer

                            1. קריאה ל-MessageBoxA

                            ה-stack נבנה ידנית:

                            סדר הפרמטרים (stdcall):

                            push 0 ; hWnd
                            push "hello world!" ; lpText
                            push "hello world!" ; lpCaption (או דומה)
                            push 0 ; uType
                            call MessageBoxA

                            לכן מתקבלת תיבת הודעה עם הטקסט.

                            1. יציאה

                            לאחר הקריאה:

                            מתבצע ret או קריאה ל-ExitProcess (גם כן נפתר דינמית או פשוט חזרה ל-loader).

                            למה זה עובד בלי Import Table?

                            כי:

                            הכל מחושב בזמן ריצה.

                            אין תלות ב-IAT.

                            ה-Loader רק צריך למפות את ה-image ולהריץ את ה-EntryPoint.

                            מה זה בפועל?

                            PE מינימלי עם:

                            API hashing

                            Manual export resolving

                            ללא imports סטטיים

                            ללא sections מורכבות

                            זו טכניקה נפוצה בקבצים קומפקטיים מאוד וב-shellcode.

                            פירוט ממוקד לפי הרצף הבינארי ששלחת, משלב ה-EntryPoint והלאה (x86):

                            שלב 1 — כניסה וניווט ל-Export Table של kernel32

                            הרצף:

                            8B 55 3C
                            8B 54 15 78
                            01 EA

                            פירוק:

                            8B 55 3C
                            mov edx, [ebp+3Ch]
                            קריאת ‎e_lfanew‎ (offset ל-NT headers).

                            8B 54 15 78
                            mov edx, [ebp+edx+78h]
                            גישה ל-DataDirectory → Export Table.

                            01 EA
                            add edx, ebp
                            המרה מ-RVA לכתובת מוחלטת.

                            עכשיו EDX מצביע ל-IMAGE_EXPORT_DIRECTORY.

                            שלב 2 — שליפת טבלאות ה-Export

                            הרצף:

                            8B 4A 18
                            8B 5A 20
                            01 EB
                            49

                            פירוק:

                            8B 4A 18
                            mov ecx, [edx+18h]
                            NumberOfNames.

                            8B 5A 20
                            mov ebx, [edx+20h]
                            AddressOfNames (RVA).

                            01 EB
                            add ebx, ebp
                            EBX עכשיו מצביע למערך שמות.

                            49
                            dec ecx
                            התחלת לולאה.

                            שלב 3 — לולאת hash על שמות פונקציות

                            הרצף:

                            8B 34 8B
                            01 EE
                            52
                            31 C0
                            99
                            AC
                            84 C0
                            74 07
                            C1 CA 0D
                            01 C2
                            EB F4

                            פירוק לוגי:

                            8B 34 8B
                            mov esi, [ebx+ecx*4]
                            קבלת RVA של שם פונקציה.

                            01 EE
                            add esi, ebp
                            המרה לכתובת.

                            31 C0
                            xor eax,eax
                            hash = 0.

                            לולאת תווים:

                            AC → lodsb (טעינת תו)

                            84 C0 → test al,al (סוף מחרוזת?)

                            74 07 → אם 0 → יציאה

                            C1 CA 0D → ror edx,13 (rotate)

                            01 C2 → add edx,eax (עדכון hash)

                            EB F4 → חזרה ללולאה

                            זו לולאת hashing טיפוסית לזיהוי פונקציות בלי להשאיר שמות גלויים.

                            שלב 4 — התאמת hash

                            הרצף:

                            39 FA
                            5A
                            75 E5

                            39 FA → cmp edx, edi (השוואת hash לערך קשיח)

                            75 E5 → אם לא שווה → המשך לולאה

                            כאשר נמצא hash תואם → ממשיכים לשליפת הכתובת.

                            שלב 5 — שליפת כתובת פונקציה

                            הרצף:

                            8B 5A 24
                            01 EB
                            0F B7 0C 4B
                            8B 5A 1C
                            01 EB
                            03 2C 8B

                            פירוק:

                            8B 5A 24
                            AddressOfNameOrdinals

                            0F B7 0C 4B
                            movzx ecx, word [ebx+ecx*2]
                            קבלת ordinal

                            8B 5A 1C
                            AddressOfFunctions

                            03 2C 8B
                            הוספת offset של הפונקציה

                            בסיום — מתקבל pointer לפונקציה (למשל LoadLibraryA).

                            שלב 6 — קריאה ל-LoadLibraryA

                            בהמשך מופיע:

                            6A 00
                            68 30 00 40 00
                            68 0C 00 40 00
                            6A 00
                            FF D0

                            פירוק:

                            push 0

                            push offset string

                            push offset string

                            push 0

                            FF D0 → call eax

                            EAX מכיל pointer לפונקציה שנפתרה.

                            כאן נטענת "user32".

                            שלב 7 — פתרון MessageBoxA

                            אותו תהליך hash מתבצע על export table של user32.dll עד למציאת MessageBoxA.

                            שלב 8 — קריאה ל-MessageBoxA

                            Stack נבנה כך:

                            push 0
                            push "hello world!"
                            push "hello world!"
                            push 0
                            call MessageBoxA

                            ולכן מתקבלת תיבת הודעה עם המחרוזת שמופיעה בקובץ:

                            68 65 6C 6C 6F 20 77 6F 72 6C 64 21
                            מה זה בפועל?

                            אין Import Table

                            אין IAT

                            כל ה-API נפתר דינמית

                            hashing כדי להימנע משמות גלויים

                            PE מינימלי עם loader ידני

                            זו טכניקת manual export resolving מלאה.

                            פירוק מבנה ה-PE עצמו — למה ה-Loader עדיין מוכן להריץ אותו למרות שהוא מינימלי מאוד.

                            1. DOS Header

                            התחלה:

                            4D 5A ; "MZ"
                            ...
                            3C ?? ?? ?? ?? ; e_lfanew

                            4D 5A = חתימת DOS תקינה.

                            ב-offset ‎0x3C‎ נמצא ‎e_lfanew‎ — מצביע ל-NT Headers.

                            ה-DOS stub כמעט לא קיים — אבל זה לא קריטי. ה-Loader צריך רק:

                            חתימה תקינה

                            offset חוקי ל-PE

                            1. NT Headers

                            בכתובת שמצביע ‎e_lfanew‎:

                            50 45 00 00 ; "PE\0\0"
                            4C 01 ; Machine = 0x14C (x86)
                            01 00 ; NumberOfSections = 1

                            זה מספיק כדי להיחשב PE תקני ל-32 ביט.

                            1. Optional Header (PE32)

                            החתימה:

                            0B 01 ; PE32 (לא PE32+)

                            שדות קריטיים שה-Loader חייב:

                            AddressOfEntryPoint

                            ImageBase

                            SectionAlignment

                            FileAlignment

                            SizeOfImage

                            SizeOfHeaders

                            Subsystem

                            גם אם הערכים מינימליים מאוד — כל עוד הם עקביים לוגית, ה-Loader ימשיך.

                            1. DataDirectory

                            Import Directory כאן ריק או לא שמיש.

                            זה חוקי.

                            Windows לא מחייב Import Table — רק אם יש אחת, הוא יטפל בה.

                            במקרה שלך:

                            אין IAT שימושית

                            לכן אין צורך ב-relocation imports

                            הכל נעשה בקוד

                            1. Section Table

                            מוגדרת Section אחת בלבד (למשל ‎.text‎ או אפילו בלי שם משמעותי).

                            ה-Loader צריך:

                            VirtualAddress

                            VirtualSize

                            SizeOfRawData

                            PointerToRawData

                            Characteristics עם:

                            IMAGE_SCN_MEM_EXECUTE

                            IMAGE_SCN_MEM_READ

                            אם ה-Section מסומנת executable — זה מספיק.

                            1. מיפוי לזיכרון

                            בעת הרצה:

                            Windows מקצה זיכרון בגודל ‎SizeOfImage‎.

                            מעתיק את ה-Headers.

                            מעתיק את ה-Section ל-VirtualAddress.

                            קופץ ל-ImageBase + AddressOfEntryPoint.

                            אין צורך ב-IAT כי אין Imports לעבד.

                            1. למה אין צורך ב-Relocations?

                            אם:

                            ImageBase תואם למה שה-Loader מצליח להקצות
                            או

                            הקוד משתמש ב-RVA יחסיים

                            אז relocation table לא חובה.

                            ב-PE מינימליים לעיתים:

                            פשוט מניחים ImageBase סטנדרטי

                            ואם הוא פנוי — הכל עובד

                            1. למה Windows לא “דורש יותר”?

                            ה-Loader בודק מינימום:

                            חתימות תקינות

                            מבנה NT headers סביר

                            Section Table חוקית

                            EntryPoint בתוך טווח section executable

                            זהו.

                            כל השאר אופציונלי.

                            סיכום מבני

                            הקובץ שלך הוא:

                            DOS header מינימלי

                            NT headers תקינים

                            Section אחת

                            ללא Import Table

                            ללא IAT

                            ללא Relocations משמעותיות

                            EntryPoint שמבצע manual resolving

                            לכן:

                            ה-Loader עושה רק mapping → קפיצה ל-EntryPoint → ומשם הכל קורה בקוד שלך.

                            @מתכנת-חובב - כמה אחוז ממה שהוא כתב נכון?

                            נ.ב. אני הבנתי רק 3 אחוז ממה שהוא כתב, (וגם זה גוזמה)

                            מתכנת חובבמ תגובה 1 תגובה אחרונה
                            0
                            • א אביגדור ברמן

                              גיפיטי מסביר מה הולך שם בבינארי - בספויילר

                              הסבר טכני תמציתי, שלב-אחר-שלב, למה שהקובץ עושה בפועל:

                              1. טעינה ע״י ה-Loader

                              תחילת הקובץ מכילה חתימות MZ ו-PE\0\0.

                              ה-Loader של Windows מזהה זאת כ-PE, ממפה את ה-Image לזיכרון לפי ה-headers ומקפיץ ל-EntryPoint.

                              1. אין Import Table רגילה

                              ה-DataDirectory של Imports ריק/לא בשימוש.

                              לכן אין IAT סטטית.

                              במקום זאת הקוד פותר APIs בזמן ריצה (manual resolving).

                              1. קבלת כתובת בסיס של מודולים (גישה ל-PEB)

                              ב-EntryPoint מתבצעת גישה ל-PEB דרך ה-segment register (ב-x86 דרך ‎FS:[0x30]‎).

                              מהלך טיפוסי:

                              קריאה ל-PEB

                              כניסה ל-PEB_LDR_DATA

                              מעבר על רשימת InMemoryOrderModuleList

                              כך מאתרים את:

                              ‎kernel32.dll‎ (כבר טעון בתהליך)

                              1. מציאת Export Table של kernel32

                              לאחר שיש BaseAddress של kernel32:

                              קריאת offset ‎e_lfanew‎ מתוך DOS header

                              קפיצה ל-NT Headers

                              גישה ל-DataDirectory → Export Table

                              חישוב כתובות:

                              AddressOfNames

                              AddressOfFunctions

                              AddressOfNameOrdinals

                              1. לולאת Hash על שמות פונקציות

                              הקוד עובר על כל שם פונקציה ב-Export Table:

                              מבנה אופייני שנראה אצלך:

                              AC
                              84 C0
                              74 07
                              C1 CA 0D
                              01 C2

                              זו לולאה שמבצעת:

                              קריאה תו-תו

                              rotate right

                              הוספת ערך

                              יצירת hash

                              כאשר ה-hash תואם לערך קשיח שמקודד בקוד → נמצאה הפונקציה.

                              בדרך זו מאתרים:

                              LoadLibraryA

                              GetProcAddress

                              1. טעינת user32.dll

                              אחרי שיש כתובת של LoadLibraryA:

                              הקוד קורא לה עם המחרוזת "user32"

                              מתקבלת כתובת בסיס של user32.dll

                              1. מציאת MessageBoxA

                              שוב מתבצע:

                              סריקת Export Table של user32

                              חישוב hash

                              התאמה ל-MessageBoxA

                              קבלת ה-function pointer

                              1. קריאה ל-MessageBoxA

                              ה-stack נבנה ידנית:

                              סדר הפרמטרים (stdcall):

                              push 0 ; hWnd
                              push "hello world!" ; lpText
                              push "hello world!" ; lpCaption (או דומה)
                              push 0 ; uType
                              call MessageBoxA

                              לכן מתקבלת תיבת הודעה עם הטקסט.

                              1. יציאה

                              לאחר הקריאה:

                              מתבצע ret או קריאה ל-ExitProcess (גם כן נפתר דינמית או פשוט חזרה ל-loader).

                              למה זה עובד בלי Import Table?

                              כי:

                              הכל מחושב בזמן ריצה.

                              אין תלות ב-IAT.

                              ה-Loader רק צריך למפות את ה-image ולהריץ את ה-EntryPoint.

                              מה זה בפועל?

                              PE מינימלי עם:

                              API hashing

                              Manual export resolving

                              ללא imports סטטיים

                              ללא sections מורכבות

                              זו טכניקה נפוצה בקבצים קומפקטיים מאוד וב-shellcode.

                              פירוט ממוקד לפי הרצף הבינארי ששלחת, משלב ה-EntryPoint והלאה (x86):

                              שלב 1 — כניסה וניווט ל-Export Table של kernel32

                              הרצף:

                              8B 55 3C
                              8B 54 15 78
                              01 EA

                              פירוק:

                              8B 55 3C
                              mov edx, [ebp+3Ch]
                              קריאת ‎e_lfanew‎ (offset ל-NT headers).

                              8B 54 15 78
                              mov edx, [ebp+edx+78h]
                              גישה ל-DataDirectory → Export Table.

                              01 EA
                              add edx, ebp
                              המרה מ-RVA לכתובת מוחלטת.

                              עכשיו EDX מצביע ל-IMAGE_EXPORT_DIRECTORY.

                              שלב 2 — שליפת טבלאות ה-Export

                              הרצף:

                              8B 4A 18
                              8B 5A 20
                              01 EB
                              49

                              פירוק:

                              8B 4A 18
                              mov ecx, [edx+18h]
                              NumberOfNames.

                              8B 5A 20
                              mov ebx, [edx+20h]
                              AddressOfNames (RVA).

                              01 EB
                              add ebx, ebp
                              EBX עכשיו מצביע למערך שמות.

                              49
                              dec ecx
                              התחלת לולאה.

                              שלב 3 — לולאת hash על שמות פונקציות

                              הרצף:

                              8B 34 8B
                              01 EE
                              52
                              31 C0
                              99
                              AC
                              84 C0
                              74 07
                              C1 CA 0D
                              01 C2
                              EB F4

                              פירוק לוגי:

                              8B 34 8B
                              mov esi, [ebx+ecx*4]
                              קבלת RVA של שם פונקציה.

                              01 EE
                              add esi, ebp
                              המרה לכתובת.

                              31 C0
                              xor eax,eax
                              hash = 0.

                              לולאת תווים:

                              AC → lodsb (טעינת תו)

                              84 C0 → test al,al (סוף מחרוזת?)

                              74 07 → אם 0 → יציאה

                              C1 CA 0D → ror edx,13 (rotate)

                              01 C2 → add edx,eax (עדכון hash)

                              EB F4 → חזרה ללולאה

                              זו לולאת hashing טיפוסית לזיהוי פונקציות בלי להשאיר שמות גלויים.

                              שלב 4 — התאמת hash

                              הרצף:

                              39 FA
                              5A
                              75 E5

                              39 FA → cmp edx, edi (השוואת hash לערך קשיח)

                              75 E5 → אם לא שווה → המשך לולאה

                              כאשר נמצא hash תואם → ממשיכים לשליפת הכתובת.

                              שלב 5 — שליפת כתובת פונקציה

                              הרצף:

                              8B 5A 24
                              01 EB
                              0F B7 0C 4B
                              8B 5A 1C
                              01 EB
                              03 2C 8B

                              פירוק:

                              8B 5A 24
                              AddressOfNameOrdinals

                              0F B7 0C 4B
                              movzx ecx, word [ebx+ecx*2]
                              קבלת ordinal

                              8B 5A 1C
                              AddressOfFunctions

                              03 2C 8B
                              הוספת offset של הפונקציה

                              בסיום — מתקבל pointer לפונקציה (למשל LoadLibraryA).

                              שלב 6 — קריאה ל-LoadLibraryA

                              בהמשך מופיע:

                              6A 00
                              68 30 00 40 00
                              68 0C 00 40 00
                              6A 00
                              FF D0

                              פירוק:

                              push 0

                              push offset string

                              push offset string

                              push 0

                              FF D0 → call eax

                              EAX מכיל pointer לפונקציה שנפתרה.

                              כאן נטענת "user32".

                              שלב 7 — פתרון MessageBoxA

                              אותו תהליך hash מתבצע על export table של user32.dll עד למציאת MessageBoxA.

                              שלב 8 — קריאה ל-MessageBoxA

                              Stack נבנה כך:

                              push 0
                              push "hello world!"
                              push "hello world!"
                              push 0
                              call MessageBoxA

                              ולכן מתקבלת תיבת הודעה עם המחרוזת שמופיעה בקובץ:

                              68 65 6C 6C 6F 20 77 6F 72 6C 64 21
                              מה זה בפועל?

                              אין Import Table

                              אין IAT

                              כל ה-API נפתר דינמית

                              hashing כדי להימנע משמות גלויים

                              PE מינימלי עם loader ידני

                              זו טכניקת manual export resolving מלאה.

                              פירוק מבנה ה-PE עצמו — למה ה-Loader עדיין מוכן להריץ אותו למרות שהוא מינימלי מאוד.

                              1. DOS Header

                              התחלה:

                              4D 5A ; "MZ"
                              ...
                              3C ?? ?? ?? ?? ; e_lfanew

                              4D 5A = חתימת DOS תקינה.

                              ב-offset ‎0x3C‎ נמצא ‎e_lfanew‎ — מצביע ל-NT Headers.

                              ה-DOS stub כמעט לא קיים — אבל זה לא קריטי. ה-Loader צריך רק:

                              חתימה תקינה

                              offset חוקי ל-PE

                              1. NT Headers

                              בכתובת שמצביע ‎e_lfanew‎:

                              50 45 00 00 ; "PE\0\0"
                              4C 01 ; Machine = 0x14C (x86)
                              01 00 ; NumberOfSections = 1

                              זה מספיק כדי להיחשב PE תקני ל-32 ביט.

                              1. Optional Header (PE32)

                              החתימה:

                              0B 01 ; PE32 (לא PE32+)

                              שדות קריטיים שה-Loader חייב:

                              AddressOfEntryPoint

                              ImageBase

                              SectionAlignment

                              FileAlignment

                              SizeOfImage

                              SizeOfHeaders

                              Subsystem

                              גם אם הערכים מינימליים מאוד — כל עוד הם עקביים לוגית, ה-Loader ימשיך.

                              1. DataDirectory

                              Import Directory כאן ריק או לא שמיש.

                              זה חוקי.

                              Windows לא מחייב Import Table — רק אם יש אחת, הוא יטפל בה.

                              במקרה שלך:

                              אין IAT שימושית

                              לכן אין צורך ב-relocation imports

                              הכל נעשה בקוד

                              1. Section Table

                              מוגדרת Section אחת בלבד (למשל ‎.text‎ או אפילו בלי שם משמעותי).

                              ה-Loader צריך:

                              VirtualAddress

                              VirtualSize

                              SizeOfRawData

                              PointerToRawData

                              Characteristics עם:

                              IMAGE_SCN_MEM_EXECUTE

                              IMAGE_SCN_MEM_READ

                              אם ה-Section מסומנת executable — זה מספיק.

                              1. מיפוי לזיכרון

                              בעת הרצה:

                              Windows מקצה זיכרון בגודל ‎SizeOfImage‎.

                              מעתיק את ה-Headers.

                              מעתיק את ה-Section ל-VirtualAddress.

                              קופץ ל-ImageBase + AddressOfEntryPoint.

                              אין צורך ב-IAT כי אין Imports לעבד.

                              1. למה אין צורך ב-Relocations?

                              אם:

                              ImageBase תואם למה שה-Loader מצליח להקצות
                              או

                              הקוד משתמש ב-RVA יחסיים

                              אז relocation table לא חובה.

                              ב-PE מינימליים לעיתים:

                              פשוט מניחים ImageBase סטנדרטי

                              ואם הוא פנוי — הכל עובד

                              1. למה Windows לא “דורש יותר”?

                              ה-Loader בודק מינימום:

                              חתימות תקינות

                              מבנה NT headers סביר

                              Section Table חוקית

                              EntryPoint בתוך טווח section executable

                              זהו.

                              כל השאר אופציונלי.

                              סיכום מבני

                              הקובץ שלך הוא:

                              DOS header מינימלי

                              NT headers תקינים

                              Section אחת

                              ללא Import Table

                              ללא IAT

                              ללא Relocations משמעותיות

                              EntryPoint שמבצע manual resolving

                              לכן:

                              ה-Loader עושה רק mapping → קפיצה ל-EntryPoint → ומשם הכל קורה בקוד שלך.

                              @מתכנת-חובב - כמה אחוז ממה שהוא כתב נכון?

                              נ.ב. אני הבנתי רק 3 אחוז ממה שהוא כתב, (וגם זה גוזמה)

                              מתכנת חובבמ מנותק
                              מתכנת חובבמ מנותק
                              מתכנת חובב
                              מדריכים
                              כתב נערך לאחרונה על ידי
                              #25

                              @אביגדור-ברמן בגדול נכון אבל הוא חיסר דברים
                              בכל אופן הוא כתב את זה כל כך לא ברור שלא יודע אם אני הייתי מבין את זה...
                              תעבור לג'מיני הוא הרבה יותר טוב להסביר דברים מורכבים

                              צריך עזרה בשחזור מידע? ייעוץ? egozkokus1@gmail.com

                              תגובה 1 תגובה אחרונה
                              2

                              • התחברות

                              • אין לך חשבון עדיין? הרשמה

                              • התחברו או הירשמו כדי לחפש.
                              • פוסט ראשון
                                פוסט אחרון
                              0
                              • חוקי הפורום
                              • פופולרי
                              • לא נפתר
                              • משתמשים
                              • חיפוש גוגל בפורום
                              • צור קשר