------------------------------------------------------------ [BUG/PRB.] VFP 9.0 FIX - INVISIBLE BREAKPOINT January 2024 ------------------------------------------------------------ CCB 1. BUG: Sometimes, vfp debugger stops at some invisible breakpoints. There is a test program from Mr. Leonid Lepin (or Mr. meligo): *PROC testbreakpoint SET STEP OFF SET ECHO OFF SET DEBUG OFF SET ESCAPE OFF SET TALK OFF SET SAFETY OFF _SCREEN.VISIBLE=.T. _SCREEN.WINDOWSTATE=2 ? 'Phantom BreakPoint' INSERT INTO tttt (f0,f1,f2,f3,f4,f5) VALUES (CHRTRAN(somestring,'\','/'),1,2,3,4,5) RETURN * END OF PROC TESTBREAKPOINT. We can set a breakpoint at the line: INSERT INTO tttt (f0,f1,f2,f3,f4,f5) VALUES (CHRTRAN(somestring,'\','/'),1,2,3,4,5) But when we run the program, the debugger stops at the line: ? 'Phantom BreakPoint' 2. CAUSE: Please refer to the head of the testbreakpoint.fxp: 00000000: FE F2 FF 20-02 01 00 00-00 D3 01 00-00 6E 01 00 ................ 00000010: 00 65 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................ 00000020: 00 00 00 00-00 00 00 DB-85 00 00 00-00 25 00 00 ................ 00000030: 00 00 00 00-00 00 00 00-00 35 01 00-00 0C 00 00 ................ 00000040: 00 1D 01 00-00 00 00 A5-40 33 00 00-00 85 BA 00 ................ 00000050: 06 00 47 31-1F FE 06 00-47 13 1F FE-06 00 47 0C ................ 00000060: 1F FE 06 00-47 15 1F FE-06 00 47 32-1F FE 06 00 ................ 00000070: 47 2E 1F FE-0D 00 54 E1-39 F7 00 00-10 FC 61 FD ................ 00000080: FE 0F 00 54-E1 39 F7 01-00 10 FC F8-01 02 FD FE ................ 00000090: 1E 00 02 F8-03 01 FC FB-12 00 50 68-61 6E 74 6F ..........Phanto 000000A0: 6D 20 42 72-65 61 6B 50-6F 69 6E 74-FD FE 55 00 m BreakPoint.... 000000B0: 72 BC FB 04-00 74 74 74-74 02 F7 02-00 07 F7 03 .......tttt..... 000000C0: 00 07 F7 04-00 07 F7 05-00 07 F7 06-00 07 F7 07 ................ 000000D0: 00 03 C5 02-FC 43 F7 08-00 FB 01 00-5C FB 01 00 ................ 000000E0: 2F 9D FD 07-FC F8 01 01-FD 07 FC F8-01 02 FD 07 ................ 000000F0: FC F8 01 03-FD 07 FC F8-01 04 FD 07-FC F8 01 05 ................ 00000100: FD 03 FE 04-00 42 FE 03-00 55 09 00-07 00 56 49 ..............VI 00000110: 53 49 42 4C-45 0B 00 57-49 4E 44 4F-57 53 54 41 SIBLE..WINDOWSTA 00000120: 54 45 02 00-46 30 02 00-46 31 02 00-46 32 02 00 TE..F0..F1..F2.. 00000130: 46 33 02 00-46 34 02 00-46 35 0A 00-53 4F 4D 45 F3..F4..F5..SOME 00000140: 53 54 52 49-4E 47 63 00-61 00 61 00-61 00 61 00 STRING.......... 00000150: 61 00 D2 00-F1 00 E2 01-51 05 42 00-33 00 00 00 ................ 00000160: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 64 3A ..............d: ............................................................................ 00000-00028 app head, 0x29 bytes 00029-0004D fxp head, 0x25 bytes 0004E-0004F size of main program: 0x00BA, 0x02 bytes 00050-00109 main program, 0xBA bytes 0010A-0010B number of names (variable, etc.): 0x0009, 0x02 bytes 0010C-00145 names, 0x3A bytes 00146-0015D Lineno description (debug info), 0x18 bytes 0015E-0016D Procedures/classes description (debug info), 0x10 bytes The size of the compiled p-code of the line: INSERT INTO tttt (f0,f1,f2,f3,f4,f5) VALUES (CHRTRAN(somestring,'\','/'),1,2,3,4,5) is 0x0055 bytes. The size of the compiled p-code of the line (from Mr. Pashka_J): RandFileName=sys(3)+"-"+left(sys(3),4)+"-"+left(sys(3),4)+"-"+left(sys(3),4)+"-"+sys(3)+left(sys(3),4) is 0x0055 bytes too. The size of the compiled p-code of the line (from Mr. pat mazuel): Wait "Patientiez SVP N.. Piece " + ALLTRIM(tmp_file_grid.n_piece )+ " - N.. line " + ALLTRIM(STR(tmp_file_grid.ln_nb)) Window AT 10,150 Nowait NOCLEAR is 0x0055 bytes too. I have done a lot of tests and found: If the size of the compiled p-code is 0x0055, 0x0155, 0x0255, etc., then the breakpoint is incorrect. 3. RESOLUTION: We can write some code to fix the BUG. 1, Please refer to the file vfp9fix.h: //+-------------------------------------------------------------------------- // // File: pro_ext.h // // Copyright: (c) 1999, Microsoft Corporation. // All Rights Reserved. // Information Contained Herein is Proprietary // and Confidential. // // Contents: API Header for the Library Construction Kit // // Notes: // //--------------------------------------------------------------------------- #ifndef PRO_EXT_INCLUDED #define PRO_EXT_INCLUDED #if defined(_MSC_VER) #pragma pack(push, 1) // Assume byte structure packing #endif #ifdef __cplusplus extern "C" { // Assume C declarations for C++ #endif // Fastcall calling convention #define FASTCALL _fastcall // FPFI is a 32 bit pointer to a function returning an int typedef long (*FPFI)(); // The FoxInfo structure contains the descriptions of the functions // contained in the library. typedef struct { char * funcName; /* Function name (all caps) */ FPFI function; /* Actual function address */ short parmCount; /* # parameters specified or a flag value */ char * parmTypes; /* Parameter list description */ } FoxInfo; typedef struct _FoxTable { struct _FoxTable *nextLibrary; /* Linked list of libraries */ short infoCount; /* # of functions in this library */ FoxInfo *infoPtr; /* Function list */ } FoxTable; // An expression's value typedef struct { char ev_type; char ev_padding; short ev_width; unsigned ev_length; long ev_long; double ev_real; long ev_currency; long ev_currency2; unsigned ev_handle; unsigned long ev_object; } Value; // A reference to a database or memory variable typedef struct { char l_type; short l_where, /* Database number or -1 for memory */ l_NTI, /* Variable name table offset */ l_offset, /* Index into database */ l_subs, /* # subscripts specified 0 <= x <= 2 */ l_sub1, l_sub2; /* subscript integral values */ } Locator; typedef union { Value val; Locator loc; /* An 'R' in l_type means the Locator */ /* part of this union is in use. */ } FoxParameter; // A paramter list to a library function. typedef struct { short pCount; /* Number of Parameters PASSED. */ FoxParameter p[1]; /* pCount Parameters. */ } ParamBlk; int FASTCALL _Execute(char *stmt); int FASTCALL _Evaluate(Value *val, char *expr); void FASTCALL _Error(int code); void FASTCALL _RetVal(Value *val); int FASTCALL _Store(Locator *loc, Value *val); int FASTCALL _Load(Locator *loc, Value *val); int FASTCALL _FindVar(int nti, int where, Locator *loc); int FASTCALL _NameTableIndex(char *name); #ifdef __cplusplus } // End of extern "C" { #endif #if defined(_MSC_VER) #pragma pack(pop) // Restore structure packing #endif #endif // PRO_EXT_INCLUDED 2, Please refer to the file vfp9fix.c: #include "vfp9fix.h" int __stdcall VirtualProtect(void *lpAddress, int dwSize, int flNewProtect, int *lpflOldProtect); void VFP9FixBreakPoint() { Value hmodule0retvalue; unsigned int hmodule0; unsigned int i; unsigned char *p1; unsigned char *p2; unsigned int OldProtect; _Execute("DECLARE integer GetModuleHandle IN win32api string lpfilename"); _Evaluate(&hmodule0retvalue,"GetModuleHandle(_vfp.fullname)"); hmodule0=hmodule0retvalue.ev_long; for (i=0x040000;i<0x280000;i++) { p1=hmodule0+i; if (*(p1+0x00)==0x8B && *(p1+0x01)==0x88 && *(p1+0x02)==0xE8 && *(p1+0x03)==0x02 && *(p1+0x04)==0x00 && *(p1+0x05)==0x00 && *(p1+0x06)==0x8B && *(p1+0x07)==0x11 && *(p1+0x08)==0x03 && *(p1+0x09)==0x90 && *(p1+0x0A)==0xF0 && *(p1+0x0B)==0x02 && *(p1+0x0C)==0x00 && *(p1+0x0D)==0x00 && *(p1+0x0E)==0x8B && *(p1+0x0F)==0x74 && *(p1+0x10)==0x24 && *(p1+0x11)==0x10 && *(p1+0x12)==0x8D && *(p1+0x13)==0x4B && *(p1+0x14)==0x02 && *(p1+0x15)==0x66 && *(p1+0x16)==0x89 && *(p1+0x17)==0x0A && *(p1+0x18)==0x8B && *(p1+0x19)==0xCB && *(p1+0x1A)==0x8D && *(p1+0x1B)==0x7A && *(p1+0x1C)==0x02 && *(p1+0x1D)==0x8B && *(p1+0x1E)==0xD1 && *(p1+0x1F)==0xC1 && *(p1+0x20)==0xE9 && *(p1+0x21)==0x02 && *(p1+0x22)==0xF3 && *(p1+0x23)==0xA5 && *(p1+0x24)==0x8B && *(p1+0x25)==0xCA && *(p1+0x26)==0x83 && *(p1+0x27)==0xE1 && *(p1+0x28)==0x03 && *(p1+0x29)==0xF3 && *(p1+0x2A)==0xA4 && *(p1+0x2B)==0x5F && *(p1+0x2C)==0x5E && *(p1+0x2D)==0x43 && *(p1+0x2E)==0x43 && *(p1+0x2F)==0x01 && *(p1+0x30)==0x98 && *(p1+0x31)==0xF0 && *(p1+0x32)==0x02 && *(p1+0x33)==0x00 && *(p1+0x34)==0x00 && *(p1+0x35)==0x8B && *(p1+0x36)==0xC3) { // fix vfp9.exe, vfp9r.dll // 00464C96: 8B88E8020000 mov ecx,[eax][0000002E8] // 00464C9C: 8B11 mov edx,[ecx] // 00464C9E: 0390F0020000 add edx,[eax][0000002F0] // 00464CA4: 8B742410 mov esi,[esp][00010] // 00464CA8: 8D4B02 lea ecx,[ebx][00002] // 00464CAB: 66890A mov [edx],cx // 00464CAE: 8BCB mov ecx,ebx // 00464CB0: 8D7A02 lea edi,[edx][00002] // 00464CB3: 8BD1 mov edx,ecx // 00464CB5: C1E902 shr ecx,002 // 00464CB8: F3A5 repe movsd // 00464CBA: 8BCA mov ecx,edx // 00464CBC: 83E103 and ecx,003 // 00464CBF: F3A4 repe movsb // 00464CC1: 5F pop edi // 00464CC2: 5E pop esi // 00464CC3: 43 inc ebx // 00464CC4: 43 inc ebx // 00464CC5: 0198F0020000 add [eax][0000002F0],ebx // 00464CCB: 8BC3 mov eax,ebx // fix to: // 00464C96: 8DB8E8020000 lea edi,[eax][0000002E8] // 00464C9C: 8B0F mov ecx,[edi] // 00464C9E: 8B11 mov edx,[ecx] // 00464CA0: 035708 add edx,[edi][00008] // 00464CA3: 8B742410 mov esi,[esp][00010] // 00464CA7: 80FB53 cmp bl,053 // 00464CAA: 7509 jne 000464CB5 // 00464CAC: 8B4D00 mov ecx,[ebp][00000] // 00464CAF: 3959F0 cmp [ecx][-0010],ebx // 00464CB2: 7501 jne 000464CB5 // 00464CB4: 43 inc ebx // 00464CB5: 8D4B02 lea ecx,[ebx][00002] // 00464CB8: 890A mov [edx],ecx // 00464CBA: 8BCB mov ecx,ebx // 00464CBC: 8D7A02 lea edi,[edx][00002] // 00464CBF: F3A4 repe movsb // 00464CC1: 5F pop edi // 00464CC2: 5E pop esi // 00464CC3: 43 inc ebx // 00464CC4: 43 inc ebx // 00464CC5: 0198F0020000 add [eax][0000002F0],ebx // 00464CCB: 8BC3 mov eax,ebx for (i=0x040000;i<0x280000;i++) { p2=hmodule0+i; if (*(p2+0x00)==0x8B && *(p2+0x01)==0x88 && *(p2+0x02)==0x70 && *(p2+0x03)==0x02 && *(p2+0x04)==0x00 && *(p2+0x05)==0x00 && *(p2+0x06)==0x8B && *(p2+0x07)==0x11 && *(p2+0x08)==0x03 && *(p2+0x09)==0x90 && *(p2+0x0A)==0x7C && *(p2+0x0B)==0x02 && *(p2+0x0C)==0x00 && *(p2+0x0D)==0x00 && *(p2+0x0E)==0x8B && *(p2+0x0F)==0x74 && *(p2+0x10)==0x24 && *(p2+0x11)==0x10 && *(p2+0x12)==0x8D && *(p2+0x13)==0x4B && *(p2+0x14)==0x02 && *(p2+0x15)==0x66 && *(p2+0x16)==0x89 && *(p2+0x17)==0x0A && *(p2+0x18)==0x8B && *(p2+0x19)==0xCB && *(p2+0x1A)==0x8D && *(p2+0x1B)==0x7A && *(p2+0x1C)==0x02 && *(p2+0x1D)==0x8B && *(p2+0x1E)==0xD1 && *(p2+0x1F)==0xC1 && *(p2+0x20)==0xE9 && *(p2+0x21)==0x02 && *(p2+0x22)==0xF3 && *(p2+0x23)==0xA5 && *(p2+0x24)==0x8B && *(p2+0x25)==0xCA && *(p2+0x26)==0x83 && *(p2+0x27)==0xE1 && *(p2+0x28)==0x03 && *(p2+0x29)==0xF3 && *(p2+0x2A)==0xA4 && *(p2+0x2B)==0x5F && *(p2+0x2C)==0x5E && *(p2+0x2D)==0x43 && *(p2+0x2E)==0x43 && *(p2+0x2F)==0x01 && *(p2+0x30)==0x98 && *(p2+0x31)==0x7C && *(p2+0x32)==0x02 && *(p2+0x33)==0x00 && *(p2+0x34)==0x00 && *(p2+0x35)==0x8B && *(p2+0x36)==0xC3) { // fix vfp9.exe, vfp9r.dll // 0054787A: 8B8870020000 mov ecx,[eax][000000270] // 00547880: 8B11 mov edx,[ecx] // 00547882: 03907C020000 add edx,[eax][00000027C] // 00547888: 8B742410 mov esi,[esp][00010] // 0054788C: 8D4B02 lea ecx,[ebx][00002] // 0054788F: 66890A mov [edx],cx // 00547892: 8BCB mov ecx,ebx // 00547894: 8D7A02 lea edi,[edx][00002] // 00547897: 8BD1 mov edx,ecx // 00547899: C1E902 shr ecx,002 // 0054789C: F3A5 repe movsd // 0054789E: 8BCA mov ecx,edx // 005478A0: 83E103 and ecx,003 // 005478A3: F3A4 repe movsb // 005478A5: 5F pop edi // 005478A6: 5E pop esi // 005478A7: 43 inc ebx // 005478A8: 43 inc ebx // 005478A9: 01987C020000 add [eax][00000027C],ebx // 005478AF: 8BC3 mov eax,ebx // fix to: // 0054787A: 8DB870020000 lea edi,[eax][000000270] // 00547880: 8B0F mov ecx,[edi] // 00547882: 8B11 mov edx,[ecx] // 00547884: 03570C add edx,[edi][0000C] // 00547887: 8B742410 mov esi,[esp][00010] // 0054788B: 80FB53 cmp bl,053 // 0054788E: 7509 jne 000547899 // 00547890: 8B4D00 mov ecx,[ebp][00000] // 00547893: 3959F0 cmp [ecx][-0010],ebx // 00547896: 7501 jne 000547899 // 00547898: 43 inc ebx // 00547899: 8D4B02 lea ecx,[ebx][00002] // 0054789C: 890A mov [edx],ecx // 0054789E: 8BCB mov ecx,ebx // 005478A0: 8D7A02 lea edi,[edx][00002] // 005478A3: F3A4 repe movsb // 005478A5: 5F pop edi // 005478A6: 5E pop esi // 005478A7: 43 inc ebx // 005478A8: 43 inc ebx // 005478A9: 01987C020000 add [eax][00000027C],ebx // 005478AF: 8BC3 mov eax,ebx // _Execute("_SCREEN.VISIBLE=.T."); // _Execute("WAIT WIND 'VFP9FixBreakPoint OK.'"); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p1,0x30,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p1+0x00)=0x8D; *(p1+0x01)=0xB8; *(p1+0x02)=0xE8; *(p1+0x03)=0x02; *(p1+0x04)=0x00; *(p1+0x05)=0x00; *(p1+0x06)=0x8B; *(p1+0x07)=0x0F; *(p1+0x08)=0x8B; *(p1+0x09)=0x11; *(p1+0x0A)=0x03; *(p1+0x0B)=0x57; *(p1+0x0C)=0x08; *(p1+0x0D)=0x8B; *(p1+0x0E)=0x74; *(p1+0x0F)=0x24; *(p1+0x10)=0x10; *(p1+0x11)=0x80; *(p1+0x12)=0xFB; *(p1+0x13)=0x53; *(p1+0x14)=0x75; *(p1+0x15)=0x09; *(p1+0x16)=0x8B; *(p1+0x17)=0x4D; *(p1+0x18)=0x00; *(p1+0x19)=0x39; *(p1+0x1A)=0x59; *(p1+0x1B)=0xF0; *(p1+0x1C)=0x75; *(p1+0x1D)=0x01; *(p1+0x1E)=0x43; *(p1+0x1F)=0x8D; *(p1+0x20)=0x4B; *(p1+0x21)=0x02; *(p1+0x22)=0x89; *(p1+0x23)=0x0A; *(p1+0x24)=0x8B; *(p1+0x25)=0xCB; *(p1+0x26)=0x8D; *(p1+0x27)=0x7A; *(p1+0x28)=0x02; VirtualProtect(p1,0x30,OldProtect,&OldProtect); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p2,0x30,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p2+0x00)=0x8D; *(p2+0x01)=0xB8; *(p2+0x02)=0x70; *(p2+0x03)=0x02; *(p2+0x04)=0x00; *(p2+0x05)=0x00; *(p2+0x06)=0x8B; *(p2+0x07)=0x0F; *(p2+0x08)=0x8B; *(p2+0x09)=0x11; *(p2+0x0A)=0x03; *(p2+0x0B)=0x57; *(p2+0x0C)=0x0C; *(p2+0x0D)=0x8B; *(p2+0x0E)=0x74; *(p2+0x0F)=0x24; *(p2+0x10)=0x10; *(p2+0x11)=0x80; *(p2+0x12)=0xFB; *(p2+0x13)=0x53; *(p2+0x14)=0x75; *(p2+0x15)=0x09; *(p2+0x16)=0x8B; *(p2+0x17)=0x4D; *(p2+0x18)=0x00; *(p2+0x19)=0x39; *(p2+0x1A)=0x59; *(p2+0x1B)=0xF0; *(p2+0x1C)=0x75; *(p2+0x1D)=0x01; *(p2+0x1E)=0x43; *(p2+0x1F)=0x8D; *(p2+0x20)=0x4B; *(p2+0x21)=0x02; *(p2+0x22)=0x89; *(p2+0x23)=0x0A; *(p2+0x24)=0x8B; *(p2+0x25)=0xCB; *(p2+0x26)=0x8D; *(p2+0x27)=0x7A; *(p2+0x28)=0x02; VirtualProtect(p2,0x30,OldProtect,&OldProtect); break; } } break; } } } FoxInfo myFoxInfo[]={ {"VFP9FixBreakPoint",(FPFI)VFP9FixBreakPoint,0,""}, }; FoxTable _FoxTable={ (FoxTable *)0,sizeof(myFoxInfo)/sizeof(FoxInfo),myFoxInfo }; 3, Please refer to the file make.bat: @echo off rem ;-----------------------------------------------; rem ; VFP9fix Maker Program ; rem ; Make.bat ; rem ; (C)Mr. Chen, 2009.11 ; rem ; E-mail: ccb2000@163.com ; rem ;-----------------------------------------------; rem NMAKE /f "vfp9fix.mak" CFG="vfp9fix - Win32 Release" if exist .\vfp9fix.dll del .\vfp9fix.dll if exist .\vfp9fix.obj del .\vfp9fix.obj if exist .\vfp9fix.lib del .\vfp9fix.lib if exist .\vfp9fix.exp del .\vfp9fix.exp if exist .\vfp9fix.pch del .\vfp9fix.pch cl /nologo /Gr /MD /w /W0 /Ox /Ob1 /Os /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Zm1000 /c vfp9fix.c if not exist .\vfp9fix.obj pause link kernel32.lib user32.lib uuid.lib winapims.lib /nologo /subsystem:windows /dll /incremental:no /machine:I386 /out:".\vfp9fix.dll" /implib:".\vfp9fix.lib" ".\vfp9fix.obj" Then run make.bat, we can build a VFP API Library file: vfp9fix.dll. 4, Please refer to the file f_vfp9fixbreakpointwithdll.prg: *PROC f_vfp9fixbreakpointwithdll * VFP 9.0 FIX - INVISIBLE BREAKPOINT with vfp9fix.dll * ccb2000@163.com, 2012.5 PRIVATE m.q_vfp9fixbreakpoint m.q_vfp9fixbreakpoint=.T. IF (ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0.AND.VERSION(2)>0) PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() SET LIBRARY TO ("vfp9fix.dll") ADDITIVE ON ERROR &q_erroron IF .F. PUBLIC vfp9fixbreakpoint(1) ENDI IF m.q_errnum#0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDI PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() =vfp9fixbreakpoint() ON ERROR &q_erroron IF m.q_errnum#0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDI PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() RELEASE LIBRARY ("vfp9fix.dll") ON ERROR &q_erroron IF m.q_errnum#0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDI m.q_vfp9fixbreakpoint=.T. RETU m.q_vfp9fixbreakpoint ENDI m.q_vfp9fixbreakpoint=.T. RETU m.q_vfp9fixbreakpoint * END OF PROC F_VFP9FIXBREAKPOINTWITHDLL. 5, Please refer to the file f_vfp9fixbreakpoint.prg: *PROC f_vfp9fixbreakpoint * VFP 9.0 FIX - INVISIBLE BREAKPOINT * ccb2000@163.com, 2012.5 PRIVATE m.q_vfp9fixbreakpoint m.q_vfp9fixbreakpoint=.T. IF !(ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0.AND.VERSION(2)>0) m.q_vfp9fixbreakpoint=.T. RETU m.q_vfp9fixbreakpoint ENDI DECLARE INTEGER "GetModuleHandle" IN win32api ; STRING lpfilename DECLARE INTEGER "GetCurrentProcess" IN win32api DECLARE INTEGER "ReadProcessMemory" IN win32api ; LONG hprocess,; INTEGER lpbaseaddress,; STRING @lpbuffer,; INTEGER nsize,; INTEGER lpnumberofbytesread DECLARE INTEGER "WriteProcessMemory" IN win32api ; LONG hprocess,; INTEGER lpbaseaddress,; STRING lpbuffer,; INTEGER nsize,; INTEGER lpnumberofbyteswritten DECLARE INTEGER "VirtualProtect" IN win32api ; INTEGER lpaddress,; INTEGER dwsize,; INTEGER flnewprotect,; INTEGER @lpfloldprotect IF .F. PUBLIC getmodulehandle(1) PUBLIC getcurrentprocess(1) PUBLIC readprocessmemory(1) PUBLIC writeprocessmemory(1) PUBLIC virtualprotect(1) ENDIF PRIVATE m.q_hmodule0 m.q_hmodule0=0 m.q_hmodule0=getmodulehandle(_VFP.FULLNAME) IF !m.q_hmodule0>0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDIF * for (i=0x040000;i<0x280000;i++) * { * p1=hmodule0+i; * if (*(p1+0x00)==0x8B && * *(p1+0x01)==0x88 && * *(p1+0x02)==0xE8 && * *(p1+0x03)==0x02 && * *(p1+0x04)==0x00 && * *(p1+0x05)==0x00 && * *(p1+0x06)==0x8B && * *(p1+0x07)==0x11 && * *(p1+0x08)==0x03 && * *(p1+0x09)==0x90 && * *(p1+0x0A)==0xF0 && * *(p1+0x0B)==0x02 && * *(p1+0x0C)==0x00 && * *(p1+0x0D)==0x00 && * *(p1+0x0E)==0x8B && * *(p1+0x0F)==0x74 && * *(p1+0x10)==0x24 && * *(p1+0x11)==0x10 && * *(p1+0x12)==0x8D && * *(p1+0x13)==0x4B && * *(p1+0x14)==0x02 && * *(p1+0x15)==0x66 && * *(p1+0x16)==0x89 && * *(p1+0x17)==0x0A && * *(p1+0x18)==0x8B && * *(p1+0x19)==0xCB && * *(p1+0x1A)==0x8D && * *(p1+0x1B)==0x7A && * *(p1+0x1C)==0x02 && * *(p1+0x1D)==0x8B && * *(p1+0x1E)==0xD1 && * *(p1+0x1F)==0xC1 && * *(p1+0x20)==0xE9 && * *(p1+0x21)==0x02 && * *(p1+0x22)==0xF3 && * *(p1+0x23)==0xA5 && * *(p1+0x24)==0x8B && * *(p1+0x25)==0xCA && * *(p1+0x26)==0x83 && * *(p1+0x27)==0xE1 && * *(p1+0x28)==0x03 && * *(p1+0x29)==0xF3 && * *(p1+0x2A)==0xA4 && * *(p1+0x2B)==0x5F && * *(p1+0x2C)==0x5E && * *(p1+0x2D)==0x43 && * *(p1+0x2E)==0x43 && * *(p1+0x2F)==0x01 && * *(p1+0x30)==0x98 && * *(p1+0x31)==0xF0 && * *(p1+0x32)==0x02 && * *(p1+0x33)==0x00 && * *(p1+0x34)==0x00 && * *(p1+0x35)==0x8B && * *(p1+0x36)==0xC3) * { * * // fix vfp9.exe, vfp9r.dll * // 00464C96: 8B88E8020000 mov ecx,[eax][0000002E8] * // 00464C9C: 8B11 mov edx,[ecx] * // 00464C9E: 0390F0020000 add edx,[eax][0000002F0] * // 00464CA4: 8B742410 mov esi,[esp][00010] * // 00464CA8: 8D4B02 lea ecx,[ebx][00002] * // 00464CAB: 66890A mov [edx],cx * // 00464CAE: 8BCB mov ecx,ebx * // 00464CB0: 8D7A02 lea edi,[edx][00002] * // 00464CB3: 8BD1 mov edx,ecx * // 00464CB5: C1E902 shr ecx,002 * // 00464CB8: F3A5 repe movsd * // 00464CBA: 8BCA mov ecx,edx * // 00464CBC: 83E103 and ecx,003 * // 00464CBF: F3A4 repe movsb * // 00464CC1: 5F pop edi * // 00464CC2: 5E pop esi * // 00464CC3: 43 inc ebx * // 00464CC4: 43 inc ebx * // 00464CC5: 0198F0020000 add [eax][0000002F0],ebx * // 00464CCB: 8BC3 mov eax,ebx * * // fix to: * // 00464C96: 8DB8E8020000 lea edi,[eax][0000002E8] * // 00464C9C: 8B0F mov ecx,[edi] * // 00464C9E: 8B11 mov edx,[ecx] * // 00464CA0: 035708 add edx,[edi][00008] * // 00464CA3: 8B742410 mov esi,[esp][00010] * // 00464CA7: 80FB53 cmp bl,053 * // 00464CAA: 7509 jne 000464CB5 * // 00464CAC: 8B4D00 mov ecx,[ebp][00000] * // 00464CAF: 3959F0 cmp [ecx][-0010],ebx * // 00464CB2: 7501 jne 000464CB5 * // 00464CB4: 43 inc ebx * // 00464CB5: 8D4B02 lea ecx,[ebx][00002] * // 00464CB8: 890A mov [edx],ecx * // 00464CBA: 8BCB mov ecx,ebx * // 00464CBC: 8D7A02 lea edi,[edx][00002] * // 00464CBF: F3A4 repe movsb * // 00464CC1: 5F pop edi * // 00464CC2: 5E pop esi * // 00464CC3: 43 inc ebx * // 00464CC4: 43 inc ebx * // 00464CC5: 0198F0020000 add [eax][0000002F0],ebx * // 00464CCB: 8BC3 mov eax,ebx PRIVATE m.q_str1 m.q_str1=REPL(CHR(0),0x280000-0x040000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000,@m.q_str1,LEN(m.q_str1),0) PRIVATE m.q_p1_nn m.q_p1_nn=1 DO WHILE .T. PRIVATE m.q_p1 m.q_p1=AT(CHR(0x8b)+; CHR(0x88)+; CHR(0xe8)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0x11)+; CHR(0x03)+; CHR(0x90)+; CHR(0xf0)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0x74)+; CHR(0x24)+; CHR(0x10)+; CHR(0x8d)+; CHR(0x4b)+; CHR(0x02)+; CHR(0x66)+; CHR(0x89)+; CHR(0x0a)+; CHR(0x8b)+; CHR(0xcb)+; CHR(0x8d)+; CHR(0x7a)+; CHR(0x02)+; CHR(0x8b)+; CHR(0xd1)+; CHR(0xc1)+; CHR(0xe9)+; CHR(0x02)+; CHR(0xf3)+; CHR(0xa5)+; CHR(0x8b)+; CHR(0xca)+; CHR(0x83)+; CHR(0xe1)+; CHR(0x03)+; CHR(0xf3)+; CHR(0xa4)+; CHR(0x5f)+; CHR(0x5e)+; CHR(0x43)+; CHR(0x43)+; CHR(0x01)+; CHR(0x98)+; CHR(0xf0)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0xc3),m.q_str1,m.q_p1_nn) IF !m.q_p1>0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDIF m.q_p1=m.q_p1-0x00 IF !(SUBS(m.q_str1,m.q_p1+0x00,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x01,1)==CHR(0x88).AND.; SUBS(m.q_str1,m.q_p1+0x02,1)==CHR(0xe8).AND.; SUBS(m.q_str1,m.q_p1+0x03,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x04,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x05,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x06,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x07,1)==CHR(0x11).AND.; SUBS(m.q_str1,m.q_p1+0x08,1)==CHR(0x03).AND.; SUBS(m.q_str1,m.q_p1+0x09,1)==CHR(0x90).AND.; SUBS(m.q_str1,m.q_p1+0x0a,1)==CHR(0xf0).AND.; SUBS(m.q_str1,m.q_p1+0x0b,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x0c,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x0d,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x0e,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x0f,1)==CHR(0x74).AND.; SUBS(m.q_str1,m.q_p1+0x10,1)==CHR(0x24).AND.; SUBS(m.q_str1,m.q_p1+0x11,1)==CHR(0x10).AND.; SUBS(m.q_str1,m.q_p1+0x12,1)==CHR(0x8d).AND.; SUBS(m.q_str1,m.q_p1+0x13,1)==CHR(0x4b).AND.; SUBS(m.q_str1,m.q_p1+0x14,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x15,1)==CHR(0x66).AND.; SUBS(m.q_str1,m.q_p1+0x16,1)==CHR(0x89).AND.; SUBS(m.q_str1,m.q_p1+0x17,1)==CHR(0x0a).AND.; SUBS(m.q_str1,m.q_p1+0x18,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x19,1)==CHR(0xcb).AND.; SUBS(m.q_str1,m.q_p1+0x1a,1)==CHR(0x8d).AND.; SUBS(m.q_str1,m.q_p1+0x1b,1)==CHR(0x7a).AND.; SUBS(m.q_str1,m.q_p1+0x1c,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x1d,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x1e,1)==CHR(0xd1).AND.; SUBS(m.q_str1,m.q_p1+0x1f,1)==CHR(0xc1).AND.; SUBS(m.q_str1,m.q_p1+0x20,1)==CHR(0xe9).AND.; SUBS(m.q_str1,m.q_p1+0x21,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x22,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x23,1)==CHR(0xa5).AND.; SUBS(m.q_str1,m.q_p1+0x24,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x25,1)==CHR(0xca).AND.; SUBS(m.q_str1,m.q_p1+0x26,1)==CHR(0x83).AND.; SUBS(m.q_str1,m.q_p1+0x27,1)==CHR(0xe1).AND.; SUBS(m.q_str1,m.q_p1+0x28,1)==CHR(0x03).AND.; SUBS(m.q_str1,m.q_p1+0x29,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x2a,1)==CHR(0xa4).AND.; SUBS(m.q_str1,m.q_p1+0x2b,1)==CHR(0x5f).AND.; SUBS(m.q_str1,m.q_p1+0x2c,1)==CHR(0x5e).AND.; SUBS(m.q_str1,m.q_p1+0x2d,1)==CHR(0x43).AND.; SUBS(m.q_str1,m.q_p1+0x2e,1)==CHR(0x43).AND.; SUBS(m.q_str1,m.q_p1+0x2f,1)==CHR(0x01).AND.; SUBS(m.q_str1,m.q_p1+0x30,1)==CHR(0x98).AND.; SUBS(m.q_str1,m.q_p1+0x31,1)==CHR(0xf0).AND.; SUBS(m.q_str1,m.q_p1+0x32,1)==CHR(0x02).AND.; SUBS(m.q_str1,m.q_p1+0x33,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x34,1)==CHR(0x00).AND.; SUBS(m.q_str1,m.q_p1+0x35,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x36,1)==CHR(0xc3)) m.q_p1_nn=m.q_p1_nn+1 LOOP ENDIF EXIT ENDDO * for (i=0x040000;i<0x280000;i++) * { * p2=hmodule0+i; * if (*(p2+0x00)==0x8B && * *(p2+0x01)==0x88 && * *(p2+0x02)==0x70 && * *(p2+0x03)==0x02 && * *(p2+0x04)==0x00 && * *(p2+0x05)==0x00 && * *(p2+0x06)==0x8B && * *(p2+0x07)==0x11 && * *(p2+0x08)==0x03 && * *(p2+0x09)==0x90 && * *(p2+0x0A)==0x7C && * *(p2+0x0B)==0x02 && * *(p2+0x0C)==0x00 && * *(p2+0x0D)==0x00 && * *(p2+0x0E)==0x8B && * *(p2+0x0F)==0x74 && * *(p2+0x10)==0x24 && * *(p2+0x11)==0x10 && * *(p2+0x12)==0x8D && * *(p2+0x13)==0x4B && * *(p2+0x14)==0x02 && * *(p2+0x15)==0x66 && * *(p2+0x16)==0x89 && * *(p2+0x17)==0x0A && * *(p2+0x18)==0x8B && * *(p2+0x19)==0xCB && * *(p2+0x1A)==0x8D && * *(p2+0x1B)==0x7A && * *(p2+0x1C)==0x02 && * *(p2+0x1D)==0x8B && * *(p2+0x1E)==0xD1 && * *(p2+0x1F)==0xC1 && * *(p2+0x20)==0xE9 && * *(p2+0x21)==0x02 && * *(p2+0x22)==0xF3 && * *(p2+0x23)==0xA5 && * *(p2+0x24)==0x8B && * *(p2+0x25)==0xCA && * *(p2+0x26)==0x83 && * *(p2+0x27)==0xE1 && * *(p2+0x28)==0x03 && * *(p2+0x29)==0xF3 && * *(p2+0x2A)==0xA4 && * *(p2+0x2B)==0x5F && * *(p2+0x2C)==0x5E && * *(p2+0x2D)==0x43 && * *(p2+0x2E)==0x43 && * *(p2+0x2F)==0x01 && * *(p2+0x30)==0x98 && * *(p2+0x31)==0x7C && * *(p2+0x32)==0x02 && * *(p2+0x33)==0x00 && * *(p2+0x34)==0x00 && * *(p2+0x35)==0x8B && * *(p2+0x36)==0xC3) * { * * // fix vfp9.exe, vfp9r.dll * // 0054787A: 8B8870020000 mov ecx,[eax][000000270] * // 00547880: 8B11 mov edx,[ecx] * // 00547882: 03907C020000 add edx,[eax][00000027C] * // 00547888: 8B742410 mov esi,[esp][00010] * // 0054788C: 8D4B02 lea ecx,[ebx][00002] * // 0054788F: 66890A mov [edx],cx * // 00547892: 8BCB mov ecx,ebx * // 00547894: 8D7A02 lea edi,[edx][00002] * // 00547897: 8BD1 mov edx,ecx * // 00547899: C1E902 shr ecx,002 * // 0054789C: F3A5 repe movsd * // 0054789E: 8BCA mov ecx,edx * // 005478A0: 83E103 and ecx,003 * // 005478A3: F3A4 repe movsb * // 005478A5: 5F pop edi * // 005478A6: 5E pop esi * // 005478A7: 43 inc ebx * // 005478A8: 43 inc ebx * // 005478A9: 01987C020000 add [eax][00000027C],ebx * // 005478AF: 8BC3 mov eax,ebx * * // fix to: * // 0054787A: 8DB870020000 lea edi,[eax][000000270] * // 00547880: 8B0F mov ecx,[edi] * // 00547882: 8B11 mov edx,[ecx] * // 00547884: 03570C add edx,[edi][0000C] * // 00547887: 8B742410 mov esi,[esp][00010] * // 0054788B: 80FB53 cmp bl,053 * // 0054788E: 7509 jne 000547899 * // 00547890: 8B4D00 mov ecx,[ebp][00000] * // 00547893: 3959F0 cmp [ecx][-0010],ebx * // 00547896: 7501 jne 000547899 * // 00547898: 43 inc ebx * // 00547899: 8D4B02 lea ecx,[ebx][00002] * // 0054789C: 890A mov [edx],ecx * // 0054789E: 8BCB mov ecx,ebx * // 005478A0: 8D7A02 lea edi,[edx][00002] * // 005478A3: F3A4 repe movsb * // 005478A5: 5F pop edi * // 005478A6: 5E pop esi * // 005478A7: 43 inc ebx * // 005478A8: 43 inc ebx * // 005478A9: 01987C020000 add [eax][00000027C],ebx * // 005478AF: 8BC3 mov eax,ebx PRIVATE m.q_str2 m.q_str2=REPL(CHR(0),0x280000-0x040000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000,@m.q_str2,LEN(m.q_str2),0) PRIVATE m.q_p2_nn m.q_p2_nn=1 DO WHILE .T. PRIVATE m.q_p2 m.q_p2=AT(CHR(0x8b)+; CHR(0x88)+; CHR(0x70)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0x11)+; CHR(0x03)+; CHR(0x90)+; CHR(0x7c)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0x74)+; CHR(0x24)+; CHR(0x10)+; CHR(0x8d)+; CHR(0x4b)+; CHR(0x02)+; CHR(0x66)+; CHR(0x89)+; CHR(0x0a)+; CHR(0x8b)+; CHR(0xcb)+; CHR(0x8d)+; CHR(0x7a)+; CHR(0x02)+; CHR(0x8b)+; CHR(0xd1)+; CHR(0xc1)+; CHR(0xe9)+; CHR(0x02)+; CHR(0xf3)+; CHR(0xa5)+; CHR(0x8b)+; CHR(0xca)+; CHR(0x83)+; CHR(0xe1)+; CHR(0x03)+; CHR(0xf3)+; CHR(0xa4)+; CHR(0x5f)+; CHR(0x5e)+; CHR(0x43)+; CHR(0x43)+; CHR(0x01)+; CHR(0x98)+; CHR(0x7c)+; CHR(0x02)+; CHR(0x00)+; CHR(0x00)+; CHR(0x8b)+; CHR(0xc3),m.q_str2,m.q_p2_nn) IF !m.q_p2>0 m.q_vfp9fixbreakpoint=.F. RETU m.q_vfp9fixbreakpoint ENDIF m.q_p2=m.q_p2-0x00 IF !(SUBS(m.q_str2,m.q_p2+0x00,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x01,1)==CHR(0x88).AND.; SUBS(m.q_str2,m.q_p2+0x02,1)==CHR(0x70).AND.; SUBS(m.q_str2,m.q_p2+0x03,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x04,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x05,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x06,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x07,1)==CHR(0x11).AND.; SUBS(m.q_str2,m.q_p2+0x08,1)==CHR(0x03).AND.; SUBS(m.q_str2,m.q_p2+0x09,1)==CHR(0x90).AND.; SUBS(m.q_str2,m.q_p2+0x0a,1)==CHR(0x7c).AND.; SUBS(m.q_str2,m.q_p2+0x0b,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x0c,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x0d,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x0e,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x0f,1)==CHR(0x74).AND.; SUBS(m.q_str2,m.q_p2+0x10,1)==CHR(0x24).AND.; SUBS(m.q_str2,m.q_p2+0x11,1)==CHR(0x10).AND.; SUBS(m.q_str2,m.q_p2+0x12,1)==CHR(0x8d).AND.; SUBS(m.q_str2,m.q_p2+0x13,1)==CHR(0x4b).AND.; SUBS(m.q_str2,m.q_p2+0x14,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0x66).AND.; SUBS(m.q_str2,m.q_p2+0x16,1)==CHR(0x89).AND.; SUBS(m.q_str2,m.q_p2+0x17,1)==CHR(0x0a).AND.; SUBS(m.q_str2,m.q_p2+0x18,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x19,1)==CHR(0xcb).AND.; SUBS(m.q_str2,m.q_p2+0x1a,1)==CHR(0x8d).AND.; SUBS(m.q_str2,m.q_p2+0x1b,1)==CHR(0x7a).AND.; SUBS(m.q_str2,m.q_p2+0x1c,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x1d,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x1e,1)==CHR(0xd1).AND.; SUBS(m.q_str2,m.q_p2+0x1f,1)==CHR(0xc1).AND.; SUBS(m.q_str2,m.q_p2+0x20,1)==CHR(0xe9).AND.; SUBS(m.q_str2,m.q_p2+0x21,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x22,1)==CHR(0xf3).AND.; SUBS(m.q_str2,m.q_p2+0x23,1)==CHR(0xa5).AND.; SUBS(m.q_str2,m.q_p2+0x24,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x25,1)==CHR(0xca).AND.; SUBS(m.q_str2,m.q_p2+0x26,1)==CHR(0x83).AND.; SUBS(m.q_str2,m.q_p2+0x27,1)==CHR(0xe1).AND.; SUBS(m.q_str2,m.q_p2+0x28,1)==CHR(0x03).AND.; SUBS(m.q_str2,m.q_p2+0x29,1)==CHR(0xf3).AND.; SUBS(m.q_str2,m.q_p2+0x2a,1)==CHR(0xa4).AND.; SUBS(m.q_str2,m.q_p2+0x2b,1)==CHR(0x5f).AND.; SUBS(m.q_str2,m.q_p2+0x2c,1)==CHR(0x5e).AND.; SUBS(m.q_str2,m.q_p2+0x2d,1)==CHR(0x43).AND.; SUBS(m.q_str2,m.q_p2+0x2e,1)==CHR(0x43).AND.; SUBS(m.q_str2,m.q_p2+0x2f,1)==CHR(0x01).AND.; SUBS(m.q_str2,m.q_p2+0x30,1)==CHR(0x98).AND.; SUBS(m.q_str2,m.q_p2+0x31,1)==CHR(0x7c).AND.; SUBS(m.q_str2,m.q_p2+0x32,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x33,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x34,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x35,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x36,1)==CHR(0xc3)) m.q_p2_nn=m.q_p2_nn+1 LOOP ENDIF EXIT ENDDO * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p1,0x30,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p1+0x00)=0x8D; * *(p1+0x01)=0xB8; * *(p1+0x02)=0xE8; * *(p1+0x03)=0x02; * *(p1+0x04)=0x00; * *(p1+0x05)=0x00; * *(p1+0x06)=0x8B; * *(p1+0x07)=0x0F; * *(p1+0x08)=0x8B; * *(p1+0x09)=0x11; * *(p1+0x0A)=0x03; * *(p1+0x0B)=0x57; * *(p1+0x0C)=0x08; * *(p1+0x0D)=0x8B; * *(p1+0x0E)=0x74; * *(p1+0x0F)=0x24; * *(p1+0x10)=0x10; * *(p1+0x11)=0x80; * *(p1+0x12)=0xFB; * *(p1+0x13)=0x53; * *(p1+0x14)=0x75; * *(p1+0x15)=0x09; * *(p1+0x16)=0x8B; * *(p1+0x17)=0x4D; * *(p1+0x18)=0x00; * *(p1+0x19)=0x39; * *(p1+0x1A)=0x59; * *(p1+0x1B)=0xF0; * *(p1+0x1C)=0x75; * *(p1+0x1D)=0x01; * *(p1+0x1E)=0x43; * *(p1+0x1F)=0x8D; * *(p1+0x20)=0x4B; * *(p1+0x21)=0x02; * *(p1+0x22)=0x89; * *(p1+0x23)=0x0A; * *(p1+0x24)=0x8B; * *(p1+0x25)=0xCB; * *(p1+0x26)=0x8D; * *(p1+0x27)=0x7A; * *(p1+0x28)=0x02; * VirtualProtect(p1,0x30,OldProtect,&OldProtect); * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p2,0x30,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p2+0x00)=0x8D; * *(p2+0x01)=0xB8; * *(p2+0x02)=0x70; * *(p2+0x03)=0x02; * *(p2+0x04)=0x00; * *(p2+0x05)=0x00; * *(p2+0x06)=0x8B; * *(p2+0x07)=0x0F; * *(p2+0x08)=0x8B; * *(p2+0x09)=0x11; * *(p2+0x0A)=0x03; * *(p2+0x0B)=0x57; * *(p2+0x0C)=0x0C; * *(p2+0x0D)=0x8B; * *(p2+0x0E)=0x74; * *(p2+0x0F)=0x24; * *(p2+0x10)=0x10; * *(p2+0x11)=0x80; * *(p2+0x12)=0xFB; * *(p2+0x13)=0x53; * *(p2+0x14)=0x75; * *(p2+0x15)=0x09; * *(p2+0x16)=0x8B; * *(p2+0x17)=0x4D; * *(p2+0x18)=0x00; * *(p2+0x19)=0x39; * *(p2+0x1A)=0x59; * *(p2+0x1B)=0xF0; * *(p2+0x1C)=0x75; * *(p2+0x1D)=0x01; * *(p2+0x1E)=0x43; * *(p2+0x1F)=0x8D; * *(p2+0x20)=0x4B; * *(p2+0x21)=0x02; * *(p2+0x22)=0x89; * *(p2+0x23)=0x0A; * *(p2+0x24)=0x8B; * *(p2+0x25)=0xCB; * *(p2+0x26)=0x8D; * *(p2+0x27)=0x7A; * *(p2+0x28)=0x02; * VirtualProtect(p2,0x30,OldProtect,&OldProtect); PRIVATE m.q_str1 m.q_str1=REPL(CHR(0),0x30) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000+m.q_p1-1+0x00,@m.q_str1,LEN(m.q_str1),0) m.q_str1=STUFF(m.q_str1,0x00+1,1,CHR(0x8d)) m.q_str1=STUFF(m.q_str1,0x01+1,1,CHR(0xb8)) m.q_str1=STUFF(m.q_str1,0x02+1,1,CHR(0xe8)) m.q_str1=STUFF(m.q_str1,0x03+1,1,CHR(0x02)) m.q_str1=STUFF(m.q_str1,0x04+1,1,CHR(0x00)) m.q_str1=STUFF(m.q_str1,0x05+1,1,CHR(0x00)) m.q_str1=STUFF(m.q_str1,0x06+1,1,CHR(0x8b)) m.q_str1=STUFF(m.q_str1,0x07+1,1,CHR(0x0f)) m.q_str1=STUFF(m.q_str1,0x08+1,1,CHR(0x8b)) m.q_str1=STUFF(m.q_str1,0x09+1,1,CHR(0x11)) m.q_str1=STUFF(m.q_str1,0x0a+1,1,CHR(0x03)) m.q_str1=STUFF(m.q_str1,0x0b+1,1,CHR(0x57)) m.q_str1=STUFF(m.q_str1,0x0c+1,1,CHR(0x08)) m.q_str1=STUFF(m.q_str1,0x0d+1,1,CHR(0x8b)) m.q_str1=STUFF(m.q_str1,0x0e+1,1,CHR(0x74)) m.q_str1=STUFF(m.q_str1,0x0f+1,1,CHR(0x24)) m.q_str1=STUFF(m.q_str1,0x10+1,1,CHR(0x10)) m.q_str1=STUFF(m.q_str1,0x11+1,1,CHR(0x80)) m.q_str1=STUFF(m.q_str1,0x12+1,1,CHR(0xfb)) m.q_str1=STUFF(m.q_str1,0x13+1,1,CHR(0x53)) m.q_str1=STUFF(m.q_str1,0x14+1,1,CHR(0x75)) m.q_str1=STUFF(m.q_str1,0x15+1,1,CHR(0x09)) m.q_str1=STUFF(m.q_str1,0x16+1,1,CHR(0x8b)) m.q_str1=STUFF(m.q_str1,0x17+1,1,CHR(0x4d)) m.q_str1=STUFF(m.q_str1,0x18+1,1,CHR(0x00)) m.q_str1=STUFF(m.q_str1,0x19+1,1,CHR(0x39)) m.q_str1=STUFF(m.q_str1,0x1a+1,1,CHR(0x59)) m.q_str1=STUFF(m.q_str1,0x1b+1,1,CHR(0xf0)) m.q_str1=STUFF(m.q_str1,0x1c+1,1,CHR(0x75)) m.q_str1=STUFF(m.q_str1,0x1d+1,1,CHR(0x01)) m.q_str1=STUFF(m.q_str1,0x1e+1,1,CHR(0x43)) m.q_str1=STUFF(m.q_str1,0x1f+1,1,CHR(0x8d)) m.q_str1=STUFF(m.q_str1,0x20+1,1,CHR(0x4b)) m.q_str1=STUFF(m.q_str1,0x21+1,1,CHR(0x02)) m.q_str1=STUFF(m.q_str1,0x22+1,1,CHR(0x89)) m.q_str1=STUFF(m.q_str1,0x23+1,1,CHR(0x0a)) m.q_str1=STUFF(m.q_str1,0x24+1,1,CHR(0x8b)) m.q_str1=STUFF(m.q_str1,0x25+1,1,CHR(0xcb)) m.q_str1=STUFF(m.q_str1,0x26+1,1,CHR(0x8d)) m.q_str1=STUFF(m.q_str1,0x27+1,1,CHR(0x7a)) m.q_str1=STUFF(m.q_str1,0x28+1,1,CHR(0x02)) PRIVATE m.q_str2 m.q_str2=REPL(CHR(0),0x30) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000+m.q_p2-1+0x00,@m.q_str2,LEN(m.q_str2),0) m.q_str2=STUFF(m.q_str2,0x00+1,1,CHR(0x8d)) m.q_str2=STUFF(m.q_str2,0x01+1,1,CHR(0xb8)) m.q_str2=STUFF(m.q_str2,0x02+1,1,CHR(0x70)) m.q_str2=STUFF(m.q_str2,0x03+1,1,CHR(0x02)) m.q_str2=STUFF(m.q_str2,0x04+1,1,CHR(0x00)) m.q_str2=STUFF(m.q_str2,0x05+1,1,CHR(0x00)) m.q_str2=STUFF(m.q_str2,0x06+1,1,CHR(0x8b)) m.q_str2=STUFF(m.q_str2,0x07+1,1,CHR(0x0f)) m.q_str2=STUFF(m.q_str2,0x08+1,1,CHR(0x8b)) m.q_str2=STUFF(m.q_str2,0x09+1,1,CHR(0x11)) m.q_str2=STUFF(m.q_str2,0x0a+1,1,CHR(0x03)) m.q_str2=STUFF(m.q_str2,0x0b+1,1,CHR(0x57)) m.q_str2=STUFF(m.q_str2,0x0c+1,1,CHR(0x0c)) m.q_str2=STUFF(m.q_str2,0x0d+1,1,CHR(0x8b)) m.q_str2=STUFF(m.q_str2,0x0e+1,1,CHR(0x74)) m.q_str2=STUFF(m.q_str2,0x0f+1,1,CHR(0x24)) m.q_str2=STUFF(m.q_str2,0x10+1,1,CHR(0x10)) m.q_str2=STUFF(m.q_str2,0x11+1,1,CHR(0x80)) m.q_str2=STUFF(m.q_str2,0x12+1,1,CHR(0xfb)) m.q_str2=STUFF(m.q_str2,0x13+1,1,CHR(0x53)) m.q_str2=STUFF(m.q_str2,0x14+1,1,CHR(0x75)) m.q_str2=STUFF(m.q_str2,0x15+1,1,CHR(0x09)) m.q_str2=STUFF(m.q_str2,0x16+1,1,CHR(0x8b)) m.q_str2=STUFF(m.q_str2,0x17+1,1,CHR(0x4d)) m.q_str2=STUFF(m.q_str2,0x18+1,1,CHR(0x00)) m.q_str2=STUFF(m.q_str2,0x19+1,1,CHR(0x39)) m.q_str2=STUFF(m.q_str2,0x1a+1,1,CHR(0x59)) m.q_str2=STUFF(m.q_str2,0x1b+1,1,CHR(0xf0)) m.q_str2=STUFF(m.q_str2,0x1c+1,1,CHR(0x75)) m.q_str2=STUFF(m.q_str2,0x1d+1,1,CHR(0x01)) m.q_str2=STUFF(m.q_str2,0x1e+1,1,CHR(0x43)) m.q_str2=STUFF(m.q_str2,0x1f+1,1,CHR(0x8d)) m.q_str2=STUFF(m.q_str2,0x20+1,1,CHR(0x4b)) m.q_str2=STUFF(m.q_str2,0x21+1,1,CHR(0x02)) m.q_str2=STUFF(m.q_str2,0x22+1,1,CHR(0x89)) m.q_str2=STUFF(m.q_str2,0x23+1,1,CHR(0x0a)) m.q_str2=STUFF(m.q_str2,0x24+1,1,CHR(0x8b)) m.q_str2=STUFF(m.q_str2,0x25+1,1,CHR(0xcb)) m.q_str2=STUFF(m.q_str2,0x26+1,1,CHR(0x8d)) m.q_str2=STUFF(m.q_str2,0x27+1,1,CHR(0x7a)) m.q_str2=STUFF(m.q_str2,0x28+1,1,CHR(0x02)) PRIVATE m.q_oldprotect1 m.q_oldprotect1=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x040000+m.q_p1-1,0x30,0x40,@m.q_oldprotect1) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect2 m.q_oldprotect2=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x040000+m.q_p2-1,0x30,0x40,@m.q_oldprotect2) && PAGE_EXECUTE_READWRITE =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000+m.q_p1-1+0x00,m.q_str1,LEN(m.q_str1),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x040000+m.q_p2-1+0x00,m.q_str2,LEN(m.q_str2),0) =virtualprotect(m.q_hmodule0+0x040000+m.q_p1-1,0x30,m.q_oldprotect1,@m.q_oldprotect1) =virtualprotect(m.q_hmodule0+0x040000+m.q_p2-1,0x30,m.q_oldprotect2,@m.q_oldprotect2) m.q_vfp9fixbreakpoint=.T. RETU m.q_vfp9fixbreakpoint * END OF PROC F_VFP9FIXBREAKPOINT. 6, Recommend to add the following code to the program file vfpstart.prg: * VFP9FixBreakPoint #IF ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 =f_vfp9fixbreakpoint() #ENDI then build the executable file vfpstart.exe from the program file vfpstart.prg: BUILD PROJECT vfpstart.pjx FROM vfpstart.prg BUILD EXE vfpstart.exe FROM vfpstart.pjx then add the following code to the file config.fpw: COMMAND=DO vfpstart.exe then when we run: VFP9.EXE -Cconfig.fpw vfp will run DO vfpstart.exe first, now it seems there is no invisible breakpoint. 7, The fix code can fix almost all vfp statements except the structured programming statements such as: DO CASE ... ENDCASE DO WHILE ... ENDDO FOR EACH ... ENDFOR FOR ... ENDFOR IF ... ENDIF SCAN ... ENDSCAN TRY ... ENDTRY If the structured programming statement has invisible breakpoint, we can fix it manually. For example, IF "123456789012345678901234567890123456789012345678901234567890"="12345678" we can change it to: IF "123456789012345678901234567890123456789012345678901234567890"="12345678" .OR..F. && fix invisible breakpoint We can run checkbreakpoint.prg to check the invisible breakpoints. 4. APPLIES TO: VFP 6.0.8167.0 VFP 6.0.8961.0 (SP5) VFP 7.0.0.9262 VFP 7.0.0.9465 (SP1) VFP 8.0.0.2521 VFP 8.0.0.3117 (SP1) VFP 9.0.0.2412 VFP 9.0.0.3504 (SP1) VFP 9.0.0.4611 (SP2) VFP 9.0.0.5015 (SP2) VFP 9.0.0.5411 (SP2) VFP 9.0.0.5721 (SP2) VFP 9.0.0.5815 (SP2) VFP 9.0.0.6303 (SP2) VFP 9.0.0.6602 (SP2) VFP 9.0.0.7423 (SP2) The bug has been fixed in VFP Advanced. 5. REFERENCE WEBSITES: 1, baiyujia.com: http://www.baiyujia.com http://www.baiyujia.com/vfpdocuments/f_vfp9fix224.asp 2, foxite.com: http://www.foxite.com/archives/debugger-stops-without-breakpoints-0000340467.htm http://www.foxite.com/archives/debugger-disconnect-0000256551.htm http://www.foxite.com/archives/breakpoint-0000227237.htm 3, foxclub.ru: http://forum.foxclub.ru/read.php?29,530804,page=1 4, dbmonster.com: http://www.dbmonster.com/Uwe/Forum.aspx/foxpro-menu/248/Invisible-or-phantom-breakpoints 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |