אסמבלי וחלונות

gilad_no

New member
אסמבלי וחלונות

אני מנסה לקרוא ישירות לפונקציות של חלונות שלי להגדיר טיפוס פונקציה מראש. כאשר אני קורא לתכנית המצורפת, אני מקבל את החלון אבל לאחר מכן אני מקבל הודעה לגבי אוגר ESP. יש למישהו רעיון מה הבעיה ?
 

אלדד26

New member
אין לי זמן להיכנס לזה, אבל

לפי דעתי השילוב הזה בין קריאה דרך הקומפיילר לבין ה - push - ים קודם הוא קטלני. נראה לי ש - ESP פשוט התחרבש. אני במקומך הייתי עושה את הדבר הבא: 1. תפיק LISTING של הקוד שלך 2. תקרא לפונקציה "כרגיל" ותפיק LISTING של הקוד הזה תבדוק את ההבדל בקוד האסמבלי שנוצר... לפי דעתי חסר לך איזה PUSH בהתחלה. אשמח אם תספר לפורום מה המסקנות!
 

gilad_no

New member
נפתרה הבעיה ../images/Emo45.gif

בקריאה רגילה, ESP נשמר בESI ונבדק לאחר הקריאה לפונקציה. כאשר דחפתי את הערכים בעצמי, ESP נשמר לאחר כל הדחיפות למחסנית קריאה רגילה: mov esi,esp push x push y call function הקריאה שלי: push x push y mov esi,esp call function הבעיה נפתרה בדרך פשוטה מאוד: קראתי לפונקציה בעצמי ע"י call Push(x); Push(y); __asm call pProc; בלי כל הבדיקות למיניהן. עכשיו עובד מצויין
 

gilad_no

New member
דוגמא

יצרתי פונקציה שיודעת לקרוא לפונקציות מערכת בצורה דינמית. bool Call(LPCTSTR szDll,LPCTSTR szFunction,void *pResult,LPCTSTR szParams,...) היא מחזירה TRUE או FALSE אם היא הצליחה או לא szDll - שם הDLL שבתוכו נמצאת הפונקציה szFunction - שם הפונקציה pResult - מצביע למשתנה שמכיל את התוצאה szParams - מחרוזת המציינת את הפרמטרים: w - Word l - LONG s - STRING אם זה באותיות גדולות זה מועבר by reference ולא by value בסוף הפונקציה יש את הפרמטרים האמיתיים. בקובץ המצורף ניתן לראות כיצד לקרוא לפונקציה MessageBoxA בתוך User32.dll הפונקציות מוגבלות ל128 פרמטרים אבל ניתן לשנות זאת בעזרת ההגדרה של MaxParams
 

voguemaster

New member
נחמד

אתה צריך להיזהר כשאתה משנה את שיטת הקריאה לפונקציות. WINDOWS עובדת בשיטת STDCALL והקומפיילר אחראי לשמור את התוכן של ESP עבור ה-PROLOG ולהחזיר אותו למצב הקודם בסוף ה-EPILOG, לכן אם אתה כבר מתכנן להשתמש באסמבלי, שים לב טוב לדברים האלה. בכלל, אני לא יודע אם מוגדר המאקרו invoke אבל אם כן אז הוא חוסך לך את כל הבעיה. תרגיל יפה מה שעשית עם ה-LIBRARY. בד"כ משתמשים בזה כדי להוסיף פונקציונליות לתוכנית קיימת (יענו כחלק מתהליך הפריצה.. חיחי) אלי
 

albanetc

New member
בלי כל התחכומים האלה...

כנראה יש לך בעייה עם צורת הקריאה (PASCAL או CDECL). צורה אחת אומרת, שניקוי ה-STACK זה עניין של הפונקציה, בעוד שהשנייה טוענת, שזה עניין של הקורא (אני לא זוכר איזו אומרת מה). הבעייה היא ב- DEFINE שלך: מי אמר לך ש-MESSAGEBOX היא CALLBACK? זה יעבוד גם בלי שימוש בעייתי ב-ASM, וכל מה שעלייך לעשות הוא להגדיר את הפונקציה בצורה הנכונה. תנסה מילים WINAPI או CDECL או PASCAL במקום CALLBACK. לדוגמה,
#typedef int WINAPI (*DLLPROC) (HWND, LPCTSTR, LPCTSTR, UINT) ... int iRes = pProc (NULL, dwText, dwTitle, MB_OK); ...​
הייתה לי פעם בעייה דומה ואז בזבזתי על זה יום תוך בילוי בלתי נשכח ב-DEBUGGER שדיבג WINDOWS.
 

gilad_no

New member
אני יודע שאני יכול להגדיר את המבנה!

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

gilad_no

New member
2 הערות לתשובה שלך:

MessageBox מוגדרת כCALLBACK. כל הפונקציות של חלונות מוגדרות ככה. דבר שני, ניקוי המחסנית זאת אחריות הפונקציה. זה נמצא בRET שלה. ועוד משהו, CALLBACK,PASCAL,CDECL,WINAPI כולם מגדירות אותו דבר. הם מגדירות שסדר דחיפת הפרמטרים לפונקציה צריך להתבצע מהסוף להתחלה, על מנת שבפונקציה יהיה קל לגשת אליהם (BP+2,BP+8,BP+X) לפי הסדר
 

albanetc

New member
אתה טועה ומטעה

אני אשמח לקבל הפניות או לינקים למקורות המידע שלך, בעיקר לאלה שאומרים ש" CALLBACK,PASCAL,CDECL,WINAPI כולם מגדירות אותו דבר" ו"כל הפונקציות של חלונות מוגדרות ככה". זה בניגוד מוחלט לאמור ב-MSDN.
__stdcall The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype. __cdecl This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code. WINAPI Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API entry points, you can use this for your own APIs. CALLBACK Use in place of FAR PASCAL in application callback routines such as window procedures and dialog procedures.​
 

gilad_no

New member
תיקון:

לא הסברתי את עצמי נכון, התכוונתי שהם דומים בדרך הייחוס למחסנית. ישנם הבדלים בין ההגדרות באופן יצירת הגדרת הפונקציה וכו´, אבל זה כבר נושא אחר. סליחה על הטעות
 
למעלה