---------------------------------------------------------- [BUG/PRB.] VFP 9.0 FIX - MACRO SUBSTITUTION January 2024 ---------------------------------------------------------- CCB 1. BUG: In vfp9, the procedure size can greater than 64KB. There is a program for test: *PROC testmacro SET STEP OFF SET ECHO OFF SET DEBUG OFF SET ESCAPE OFF SET TALK OFF SET SAFETY OFF _SCREEN.VISIBLE=.T. _SCREEN.WINDOWSTATE=2 PRIVATE m.x1 m.x1=".F." IF &x1 ?"Y" ELSE ?"N" ENDI WAIT RETURN * END OF PROC TESTMACRO. PROC testmacro_largeprocedure PRIVATE m.x2 m.x2="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" m.x2="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ... m.x2="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" m.x2="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" RETURN * END OF PROC TESTMACRO_LARGEPROCEDURE. The size of the procedure testmacro_largeprocedure is about 100KB, it is greater than 64KB. The program is simple, we think it will display "N" and wait any key to continue ... But when we run the program, it causes the error "Command contains unrecognized phrase/keyword (Error 36)". If we choice Ignore, it displays "Y" and wait any key to continue ... 2. CAUSE: Usually, the compiled p-code format of macro statement is: 00----01 DW p-code length 02----02 DB 0x01: macro statement 03----03+N-1 DB source code 03+N--03+N DB 0x0A: end For structured programming statements (except DO WHILE), the compiled p-code format of macro statement is: 00------01 DW p-code length 02------02 DB 0x01: macro statement 03------03+N-1 DB source code 03+N----03+N DB 0xF9 03+N+1--03+N+1 DB 0x05 03+N+2--03+N+3 DW offset of ENDIF, ENDCASE, ENDFOR, ENDSCAN 03+N+4--03+N+4 DB 0xFE: end If the procedure size is greater than 64KB, the compiled p-code format of macro statement is: 00------01 DW p-code length 02------02 DB 0x01: macro statement 03------03+N-1 DB source code 03+N----03+N DB 0xE9 03+N+1--03+N+1 DB 0x00 03+N+2--03+N+5 DD offset of ENDIF, ENDCASE, ENDFOR, ENDSCAN 03+N+6--03+N+6 DB 0xFE: end We can trace the vfp 9.0 dynamic link library VFP9R.DLL, the following code has some problems when the procedure size is greater than 64KB: 0C08F4F1 807C1EFFFE cmp byte ptr [esi+ebx-01], FE 0C08F4F6 0F8468540E00 je 0C174964 ... 0C174964: 83EE05 sub esi,005 0C174967: 8D3C1E lea edi,[esi][ebx] 0C17496A: 6A05 push 005 0C17496C: 8BD7 mov edx,edi 0C17496E: 8D4DF0 lea ecx,[ebp][-0010] 0C174971: E87E35EBFF call 00C027EF4 0C174976: C60700 mov b,[edi],000 0C174979: 46 inc esi 0C17497A: E981ABF1FF jmp 00C08F500 If the procedure size is greater than 64KB, it will be fixed to: 0C174964: 83EE05 sub esi,007 0C174967: 8D3C1E lea edi,[esi][ebx] 0C17496A: 6A05 push 007 There is another BUG: Sometimes, if the array element order is greater than 255, it can not be macro-converted. For example: PUBLIC x1(300) x1="ABC" The macro statement &x1(255) can be converted to ABC. But the macro statement &x1(256) can not be converted. The following program will fix this BUG too. 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 VFP9FixMacroSubstitution() { Value hmodule0retvalue; unsigned int hmodule0; unsigned int i; unsigned char *p0; unsigned char *p1; unsigned char *p2; unsigned char *p3; unsigned char *p4; unsigned int p0type1; unsigned int p0type2; unsigned int p1type1; unsigned int p2type1; unsigned int p3type1; unsigned int p4type1; unsigned int *p2int; unsigned int *p3int; unsigned int OldProtect; _Execute("DECLARE integer GetModuleHandle IN win32api string lpfilename"); _Evaluate(&hmodule0retvalue,"GetModuleHandle(_vfp.fullname)"); hmodule0=hmodule0retvalue.ev_long; for (i=0x080000;i<0x180000;i++) { p0=hmodule0+i; if (((*(p0+0x00)==0x80 && *(p0+0x01)==0x38 && *(p0+0x02)==0x51) || (*(p0+0x00)==0x80 && *(p0+0x01)==0x3A && *(p0+0x02)==0x51)) && *(p0+0x03)==0x0F && *(p0+0x04)==0x84 && ((*(p0+0x09)==0x66 && *(p0+0x0A)==0xC7 && *(p0+0x0B)==0x47 && *(p0+0x0C)==0x08 && *(p0+0x0D)==0x0C && *(p0+0x0E)==0x00 && *(p0+0x0F)==0xE9) || (*(p0+0x09+3)==0x66 && *(p0+0x0A+3)==0xC7 && *(p0+0x0B+3)==0x47 && *(p0+0x0C+3)==0x08 && *(p0+0x0D+3)==0x0C && *(p0+0x0E+3)==0x00 && *(p0+0x0F+3)==0xE9))) { p0type1=0; if (*(p0+0x00)==0x80 && *(p0+0x01)==0x38 && *(p0+0x02)==0x51) p0type1=0; else if (*(p0+0x00)==0x80 && *(p0+0x01)==0x3A && *(p0+0x02)==0x51) p0type1=1; p0type2=0; if (*(p0+0x09)==0x66 && *(p0+0x0A)==0xC7 && *(p0+0x0B)==0x47 && *(p0+0x0C)==0x08 && *(p0+0x0D)==0x0C && *(p0+0x0E)==0x00 && *(p0+0x0F)==0xE9) p0type2=0; else if (*(p0+0x09+3)==0x66 && *(p0+0x0A+3)==0xC7 && *(p0+0x0B+3)==0x47 && *(p0+0x0C+3)==0x08 && *(p0+0x0D+3)==0x0C && *(p0+0x0E+3)==0x00 && *(p0+0x0F+3)==0xE9) p0type2=1; // fix vfp9r.dll // 0C0B3689: 81E200400000 and edx,000004000 // 0C0B368F: BE2C000000 mov esi,00000002C // 0C0B3694: 6A00 push 000 // 0C0B3696: 81CA00880000 or edx,000008800 // 0C0B369C: 03C6 add eax,esi // 0C0B369E: 6A00 push 000 // 0C0B36A0: C1EA0B shr edx,00B // 0C0B36A3: 8BCF mov ecx,edi // 0C0B36A5: A310A2410C mov [00C41A210],eax // 0C0B36AA: E8EB9F0000 call 00C0BD69A // 0C0B36AF: 8B0D10A2410C mov ecx,[00C41A210] // 0C0B36B5: 8B45A0 mov eax,[ebp][-0060] // 0C0B36B8: 2BCE sub ecx,esi // 0C0B36BA: 85C0 test eax,eax // 0C0B36BC: 890D10A2410C mov [00C41A210],ecx // 0C0B36C2: 750E jne 00C0B36D2 // 0C0B36C4: A11CC3410C mov eax,[00C41C31C] // 0C0B36C9: 803851 cmp b,[eax],051 // 0C0B36CC: 0F8429491200 je 00C1D7FFB // 0C0B36D2: 66C747080C00 mov w,[edi][00008],0000C // 0C0B36D8: E995A2F6FF jmp 00C01D972 // fix to: // 0C0B3689: 81E200400000 and edx,000004000 // 0C0B368F: BE2C000000 mov esi,00000002C // 0C0B3694: 6A00 push 000 // 0C0B3696: 81CA00880000 or edx,000008800 // 0C0B369C: 03C6 add eax,esi // 0C0B369E: 6A00 push 000 // 0C0B36A0: C1EA0B shr edx,00B // 0C0B36A3: 8BCF mov ecx,edi // 0C0B36A5: A310A2410C mov [00C41A210],eax // 0C0B36AA: E8EB9F0000 call 00C0BD69A // 0C0B36AF: 8B0D10A2410C mov ecx,[00C41A210] // 0C0B36B5: 8B45A0 mov eax,[ebp][-0060] // 0C0B36B8: 2BCE sub ecx,esi // 0C0B36BA: 85C0 test eax,eax // 0C0B36BC: 890D10A2410C mov [00C41A210],ecx // 0C0B36C2: 750E jne 00C0B36D2 // 0C0B36C4: A11CC3410C mov eax,[00C41C31C] // 0C0B36C9: 90 nop // 0C0B36CA: 90 nop // 0C0B36CB: 90 nop // 0C0B36CC: 90 nop // 0C0B36CD: 90 nop // 0C0B36CE: 90 nop // 0C0B36CF: 90 nop // 0C0B36D0: 90 nop // 0C0B36D1: 90 nop // 0C0B36D2: 66C747080C00 mov w,[edi][00008],0000C // 0C0B36D8: E995A2F6FF jmp 00C01D972 // fix vfp9.exe // 005036AE: 81E100400000 and ecx,000004000 // 005036B4: 6A00 push 000 // 005036B6: 81C900880000 or ecx,000008800 // 005036BC: C74704FFFFFFFF mov d,[edi][00004],0FFFFFFFF // 005036C3: 8907 mov [edi],eax // 005036C5: 8B1560719300 mov edx,[000937160] // 005036CB: 6A00 push 000 // 005036CD: C1E90B shr ecx,00B // 005036D0: BE2C000000 mov esi,00000002C // 005036D5: 51 push ecx // 005036D6: 03D6 add edx,esi // 005036D8: 57 push edi // 005036D9: 891560719300 mov [000937160],edx // 005036DF: E8C6FEFFFF call 0005035AA // 005036E4: 8B0D60719300 mov ecx,[000937160] // 005036EA: 8B45A0 mov eax,[ebp][-0060] // 005036ED: 2BCE sub ecx,esi // 005036EF: 85C0 test eax,eax // 005036F1: 890D60719300 mov [000937160],ecx // 005036F7: 750F jne 000503708 // 005036F9: 8B15E0B59300 mov edx,[00093B5E0] // 005036FF: 803A51 cmp b,[edx],051 // 00503702: 0F84C9781100 je 00061AFD1 // 00503708: 8B75B0 mov esi,[ebp][-0050] // 0050370B: 66C747080C00 mov w,[edi][00008],0000C // 00503711: E9F5B8F1FF jmp 00041F00B // fix to: // 005036AE: 81E100400000 and ecx,000004000 // 005036B4: 6A00 push 000 // 005036B6: 81C900880000 or ecx,000008800 // 005036BC: C74704FFFFFFFF mov d,[edi][00004],0FFFFFFFF // 005036C3: 8907 mov [edi],eax // 005036C5: 8B1560719300 mov edx,[000937160] // 005036CB: 6A00 push 000 // 005036CD: C1E90B shr ecx,00B // 005036D0: BE2C000000 mov esi,00000002C // 005036D5: 51 push ecx // 005036D6: 03D6 add edx,esi // 005036D8: 57 push edi // 005036D9: 891560719300 mov [000937160],edx // 005036DF: E8C6FEFFFF call 0005035AA // 005036E4: 8B0D60719300 mov ecx,[000937160] // 005036EA: 8B45A0 mov eax,[ebp][-0060] // 005036ED: 2BCE sub ecx,esi // 005036EF: 85C0 test eax,eax // 005036F1: 890D60719300 mov [000937160],ecx // 005036F7: 750F jne 000503708 // 005036F9: 8B15E0B59300 mov edx,[00093B5E0] // 005036FF: 90 nop // 00503700: 90 nop // 00503701: 90 nop // 00503702: 90 nop // 00503703: 90 nop // 00503704: 90 nop // 00503705: 90 nop // 00503706: 90 nop // 00503707: 90 nop // 00503708: 8B75B0 mov esi,[ebp][-0050] // 0050370B: 66C747080C00 mov w,[edi][00008],0000C // 00503711: E9F5B8F1FF jmp 00041F00B // _Execute("_SCREEN.VISIBLE=.T."); // _Execute("WAIT WIND 'VFP9FixMacroSubstitution OK.'"); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p0,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p0+0x00)=0x90; *(p0+0x01)=0x90; *(p0+0x02)=0x90; *(p0+0x03)=0x90; *(p0+0x04)=0x90; *(p0+0x05)=0x90; *(p0+0x06)=0x90; *(p0+0x07)=0x90; *(p0+0x08)=0x90; VirtualProtect(p0,0x10,OldProtect,&OldProtect); break; } } for (i=0x000000;i<0x080000;i++) { p1=hmodule0+i; if (*(p1+0x00)==0x83 && *(p1+0x01)==0xF8 && *(p1+0x02)==0x18 && ((*(p1+0x03)==0x77 && *(p1+0x05)==0x8B && *(p1+0x06)==0xC8 && *(p1+0x07)==0xF3 && *(p1+0x08)==0xA4 && *(p1+0x09)==0x59 && *(p1+0x0A)==0x5F && *(p1+0x0B)==0x5E && *(p1+0x0C)==0xC2 && *(p1+0x0D)==0x04 && *(p1+0x0E)==0x00) || (*(p1+0x03)==0x0F && *(p1+0x04)==0x87 && *(p1+0x05+4)==0x8B && *(p1+0x06+4)==0xC8 && *(p1+0x07+4)==0xF3 && *(p1+0x08+4)==0xA4 && *(p1+0x09+4)==0x59 && *(p1+0x0A+4)==0x5F && *(p1+0x0B+4)==0x5E && *(p1+0x0C+4)==0xC2 && *(p1+0x0D+4)==0x04 && *(p1+0x0E+4)==0x00))) { p1type1=0; if (*(p1+0x03)==0x77 && *(p1+0x05)==0x8B && *(p1+0x06)==0xC8 && *(p1+0x07)==0xF3 && *(p1+0x08)==0xA4 && *(p1+0x09)==0x59 && *(p1+0x0A)==0x5F && *(p1+0x0B)==0x5E && *(p1+0x0C)==0xC2 && *(p1+0x0D)==0x04 && *(p1+0x0E)==0x00) p1type1=0; else if (*(p1+0x03)==0x0F && *(p1+0x04)==0x87 && *(p1+0x05+4)==0x8B && *(p1+0x06+4)==0xC8 && *(p1+0x07+4)==0xF3 && *(p1+0x08+4)==0xA4 && *(p1+0x09+4)==0x59 && *(p1+0x0A+4)==0x5F && *(p1+0x0B+4)==0x5E && *(p1+0x0C+4)==0xC2 && *(p1+0x0D+4)==0x04 && *(p1+0x0E+4)==0x00) p1type1=1; // fix vfp9.exe, vfp9r.dll // 0C027EF4: 56 push esi // 0C027EF5: 57 push edi // 0C027EF6: 8BF9 mov edi,ecx // 0C027EF8: 8BF2 mov esi,edx // 0C027EFA: 8B44240C mov eax,[esp][0000C] // 0C027EFE: 85C0 test eax,eax // 0C027F00: 0F8CDFD61400 jl 00C1755E5 // 0C027F06: 8BD7 mov edx,edi // 0C027F08: 2BD6 sub edx,esi // 0C027F0A: 3BD0 cmp edx,eax // 0C027F0C: 0F82B5550000 jb 00C02D4C7 // 0C027F12: 51 push ecx // 0C027F13: 8BC8 mov ecx,eax // 0C027F15: 83F818 cmp eax,018 // 0C027F18: 770A ja 00C027F24 ;; or 0F870B010000 ja 00C02629D // 0C027F1A: 8BC8 mov ecx,eax // 0C027F1C: F3A4 repe movsb // 0C027F1E: 59 pop ecx // 0C027F1F: 5F pop edi // 0C027F20: 5E pop esi // 0C027F21: C20400 retn 00004 // fix to: // 0C027EF4: 56 push esi // 0C027EF5: 57 push edi // 0C027EF6: 8BF9 mov edi,ecx // 0C027EF8: 8BF2 mov esi,edx // 0C027EFA: 8B44240C mov eax,[esp][0000C] // 0C027EFE: 85C0 test eax,eax // 0C027F00: 0F8CDFD61400 jl 00C1755E5 // 0C027F06: 8BD7 mov edx,edi // 0C027F08: 2BD6 sub edx,esi // 0C027F0A: 3BD0 cmp edx,eax // 0C027F0C: 0F82B5550000 jb 00C02D4C7 // 0C027F12: 51 push ecx // 0C027F13: 8BC8 mov ecx,eax // 0C027F15: 90 nop // 0C027F16: 90 nop // 0C027F17: 90 nop // 0C027F18: 90 nop // 0C027F19: 90 nop // 0C027F1A: 8BC8 mov ecx,eax // 0C027F1C: F3A4 repe movsb // 0C027F1E: 59 pop ecx // 0C027F1F: 5F pop edi // 0C027F20: 5E pop esi // 0C027F21: C20400 retn 00004 for (i=0x000000;i<0x080000;i++) { p2=hmodule0+i; if (*(p2+0x00)==0x33 && *(p2+0x01)==0xC9 && *(p2+0x02)==0x2B && *(p2+0x03)==0xCF && *(p2+0x04)==0x83 && *(p2+0x05)==0xE1 && *(p2+0x06)==0x03 && *(p2+0x07)==0x2B && *(p2+0x08)==0xC1 && *(p2+0x09)==0xF3 && *(p2+0x0A)==0xA4 && *(p2+0x0B)==0x8B && *(p2+0x0C)==0xC8 && *(p2+0x0D)==0xC1 && *(p2+0x0E)==0xE9 && *(p2+0x0F)==0x02 && *(p2+0x10)==0xF3 && *(p2+0x11)==0xA5 && *(p2+0x12)==0x83 && *(p2+0x13)==0xE0 && *(p2+0x14)==0x03 && ((*(p2+0x15)==0xEB) || (*(p2+0x15)==0xE9))) { p2type1=0; if (*(p2+0x15)==0xEB) p2type1=0; else if (*(p2+0x15)==0xE9) p2type1=1; // fix vfp9.exe, vfp9r.dll // 0C027F24: 33C9 xor ecx,ecx // 0C027F26: 2BCF sub ecx,edi // 0C027F28: 83E103 and ecx,003 // 0C027F2B: 2BC1 sub eax,ecx // 0C027F2D: F3A4 repe movsb // 0C027F2F: 8BC8 mov ecx,eax // 0C027F31: C1E902 shr ecx,002 // 0C027F34: F3A5 repe movsd // 0C027F36: 83E003 and eax,003 // 0C027F39: EBDF jmps 00C027F1A ;; or E9DBFEFFFF jmp 00C026192 // fix to: // 0C027F24 807C33 FA 00 CMP BYTE PTR DS:[EBX+ESI-6],0 ;; or 807C3E FA 00 CMP BYTE PTR DS:[EDI+ESI-6],0 // 0C027F29 74 04 JE SHORT vfp9r.0C027F2F // 0C027F2B 6A 05 PUSH 5 // 0C027F2D EB 02 JMP SHORT vfp9r.0C027F31 // 0C027F2F 6A 07 PUSH 7 // 0C027F31 2B3424 SUB ESI,DWORD PTR SS:[ESP] // 0C027F34 E9 30CA1400 JMP vfp9r.0C174969 // 0C027F39 90 NOP // 0C027F3A 90 NOP for (i=0x080000;i<0x200000;i++) { p3=hmodule0+i; if (*(p3+0x00)==0x83 && *(p3+0x01)==0xEE && *(p3+0x02)==0x05 && ((*(p3+0x03)==0x8D && *(p3+0x04)==0x3C && *(p3+0x05)==0x1E && *(p3+0x06)==0x6A && *(p3+0x07)==0x05 && *(p3+0x08)==0x8B && *(p3+0x09)==0xD7) || (*(p3+0x03)==0x8D && *(p3+0x04)==0x1C && *(p3+0x05)==0x37 && *(p3+0x06)==0x6A && *(p3+0x07)==0x05 && *(p3+0x08)==0x8B && *(p3+0x09)==0xD3))) { p3type1=0; if (*(p3+0x03)==0x8D && *(p3+0x04)==0x3C && *(p3+0x05)==0x1E && *(p3+0x06)==0x6A && *(p3+0x07)==0x05 && *(p3+0x08)==0x8B && *(p3+0x09)==0xD7) p3type1=0; else if (*(p3+0x03)==0x8D && *(p3+0x04)==0x1C && *(p3+0x05)==0x37 && *(p3+0x06)==0x6A && *(p3+0x07)==0x05 && *(p3+0x08)==0x8B && *(p3+0x09)==0xD3) p3type1=1; // fix vfp9.exe, vfp9r.dll // 0C174964: 83EE05 sub esi,005 // 0C174967: 8D3C1E lea edi,[esi][ebx] ;; or 8D1C37 lea ebx,[edi][esi] // 0C17496A: 6A05 push 005 // 0C17496C: 8BD7 mov edx,edi ;; or 8BD3 mov edx,ebx // 0C17496E: 8D4DF0 lea ecx,[ebp][-0010] // 0C174971: E87E35EBFF call 00C027EF4 // 0C174976: C60700 mov b,[edi],000 // 0C174979: 46 inc esi // 0C17497A: E981ABF1FF jmp 00C08F500 // fix to: // 0C174964 E9 BB35EBFF JMP vfp9r.0C027F24 // 0C174969 8D3C1E LEA EDI,DWORD PTR DS:[ESI+EBX] ;; or 8D1C37 lea ebx,[edi][esi] // 0C17496C 8BD7 MOV EDX,EDI ;; or 8BD3 mov edx,ebx // 0C17496E 8D4D F0 LEA ECX,DWORD PTR SS:[EBP-10] // 0C174971 E8 7E35EBFF CALL vfp9r.0C027EF4 // 0C174976 C607 00 MOV BYTE PTR DS:[EDI],0 // 0C174979 46 INC ESI // 0C17497A E9 81ABF1FF JMP vfp9r.0C08F500 for (i=0x080000;i<0x200000;i++) { p4=hmodule0+i; if (*(p4+0x00)==0x6A && *(p4+0x01)==0x04 && *(p4+0x02)==0x8D && *(p4+0x03)==0x55 && *(p4+0x04)==0xF0 && *(p4+0x05)==0xE8 && ((*(p4+0x0A)==0x8D && *(p4+0x0B)==0x47 && *(p4+0x0C)==0x03) || (*(p4+0x0A)==0x8D && *(p4+0x0B)==0x46 && *(p4+0x0C)==0x03)) && *(p4+0x0D)==0xE9) { p4type1=0; if (*(p4+0x0A)==0x8D && *(p4+0x0B)==0x47 && *(p4+0x0C)==0x03) p4type1=0; else if (*(p4+0x0A)==0x8D && *(p4+0x0B)==0x46 && *(p4+0x0C)==0x03) p4type1=1; // fix vfp9.exe, vfp9r.dll // 0C1749EF: 8B1588C2410C mov edx,[00C41C288] // 0C1749F5: 8D4C3AFF lea ecx,[edx][edi][-0001] ;; or 8D4C32FF lea ecx,[edx][esi][-0001] // 0C1749F9: 6A04 push 004 // 0C1749FB: 8D55F0 lea edx,[ebp][-0010] // 0C1749FE: E8F134EBFF call 00C027EF4 // 0C174A03: 8D4703 lea eax,[edi][00003] ;; or 8D4603 lea eax,[esi][00003] // 0C174A06: E9D2ABF1FF jmp 00C08F5DD // fix to: // 0C1749EF: 8B1588C2410C mov edx,[00C41C288] // 0C1749F5: 8D4C3AFF lea ecx,[edx][edi][-0001] ;; or 8D4C32FF lea ecx,[edx][esi][-0001] // 0C1749F9: 6A06 push 006 // 0C1749FB: 8D55F0 lea edx,[ebp][-0010] // 0C1749FE: E8F134EBFF call 00C027EF4 // 0C174A03: 8D4705 lea eax,[edi][00005] ;; or 8D4605 lea eax,[esi][00005] // 0C174A06: E9D2ABF1FF jmp 00C08F5DD // _Execute("_SCREEN.VISIBLE=.T."); // _Execute("WAIT WIND 'VFP9FixMacroSubstitution OK.'"); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p1,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE if (p1type1==0) { *(p1+0x00)=0x90; *(p1+0x01)=0x90; *(p1+0x02)=0x90; *(p1+0x03)=0x90; *(p1+0x04)=0x90; } else { *(p1+0x00)=0x90; *(p1+0x01)=0x90; *(p1+0x02)=0x90; *(p1+0x03)=0x90; *(p1+0x04)=0x90; *(p1+0x05)=0x90; *(p1+0x06)=0x90; *(p1+0x07)=0x90; *(p1+0x08)=0x90; } VirtualProtect(p1,0x10,OldProtect,&OldProtect); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p2,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE if (p3type1==0) { *(p2+0x00)=0x80; *(p2+0x01)=0x7C; *(p2+0x02)=0x33; *(p2+0x03)=0xFA; *(p2+0x04)=0x00; } else { *(p2+0x00)=0x80; *(p2+0x01)=0x7C; *(p2+0x02)=0x3E; *(p2+0x03)=0xFA; *(p2+0x04)=0x00; } *(p2+0x05)=0x74; *(p2+0x06)=0x04; *(p2+0x07)=0x6A; *(p2+0x08)=0x05; *(p2+0x09)=0xEB; *(p2+0x0A)=0x02; *(p2+0x0B)=0x6A; *(p2+0x0C)=0x07; *(p2+0x0D)=0x2B; *(p2+0x0E)=0x34; *(p2+0x0F)=0x24; *(p2+0x10)=0xE9; p2int=p2+0x11; *(p2int)=(p3+0x05)-(p2+0x10+5); if (p2type1==0) { *(p2+0x15)=0x90; *(p2+0x16)=0x90; } else { *(p2+0x15)=0x90; *(p2+0x16)=0x90; *(p2+0x17)=0x90; *(p2+0x18)=0x90; *(p2+0x19)=0x90; } VirtualProtect(p2,0x20,OldProtect,&OldProtect); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p3,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p3+0x00)=0xE9; p3int=p3+0x01; *(p3int)=(p2+0x00)-(p3+0x00+5); if (p3type1==0) { *(p3+0x05)=0x8D; *(p3+0x06)=0x3C; *(p3+0x07)=0x1E; } else { *(p3+0x05)=0x8D; *(p3+0x06)=0x1C; *(p3+0x07)=0x37; } VirtualProtect(p3,0x10,OldProtect,&OldProtect); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p4,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p4+0x01)=0x06; *(p4+0x0C)=0x05; VirtualProtect(p4,0x10,OldProtect,&OldProtect); break; } } break; } } break; } } break; } } } FoxInfo myFoxInfo[]={ {"VFP9FixMacroSubstitution",(FPFI)VFP9FixMacroSubstitution,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_vfp9fixmacrosubstitutionwithdll.prg: *PROC f_vfp9fixmacrosubstitutionwithdll * VFP 9.0 FIX - MACRO SUBSTITUTION with vfp9fix.dll * ccb2000@163.com, 2010.1 PRIVATE m.q_vfp9fixmacrosubstitution m.q_vfp9fixmacrosubstitution=.T. IF ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.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 vfp9fixmacrosubstitution(1) ENDI IF m.q_errnum#0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDI PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() =vfp9fixmacrosubstitution() ON ERROR &q_erroron IF m.q_errnum#0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution 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_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDI m.q_vfp9fixmacrosubstitution=.T. RETU m.q_vfp9fixmacrosubstitution ENDI m.q_vfp9fixmacrosubstitution=.T. RETU m.q_vfp9fixmacrosubstitution * END OF PROC F_VFP9FIXMACROSUBSTITUTIONWITHDLL. 5, Please refer to the file f_vfp9fixmacrosubstitution.prg: *PROC f_vfp9fixmacrosubstitution * VFP 9.0 FIX - MACRO SUBSTITUTION * ccb2000@163.com, 2010.12 PRIVATE m.q_vfp9fixmacrosubstitution m.q_vfp9fixmacrosubstitution=.T. IF !ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 m.q_vfp9fixmacrosubstitution=.T. RETU m.q_vfp9fixmacrosubstitution 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_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF * for (i=0x080000;i<0x180000;i++) * { * p0=hmodule0+i; * if (((*(p0+0x00)==0x80 && * *(p0+0x01)==0x38 && * *(p0+0x02)==0x51) || * (*(p0+0x00)==0x80 && * *(p0+0x01)==0x3A && * *(p0+0x02)==0x51)) && * *(p0+0x03)==0x0F && * *(p0+0x04)==0x84 && * ((*(p0+0x09)==0x66 && * *(p0+0x0A)==0xC7 && * *(p0+0x0B)==0x47 && * *(p0+0x0C)==0x08 && * *(p0+0x0D)==0x0C && * *(p0+0x0E)==0x00 && * *(p0+0x0F)==0xE9) || * (*(p0+0x09+3)==0x66 && * *(p0+0x0A+3)==0xC7 && * *(p0+0x0B+3)==0x47 && * *(p0+0x0C+3)==0x08 && * *(p0+0x0D+3)==0x0C && * *(p0+0x0E+3)==0x00 && * *(p0+0x0F+3)==0xE9))) * { * * p0type1=0; * if (*(p0+0x00)==0x80 && * *(p0+0x01)==0x38 && * *(p0+0x02)==0x51) * p0type1=0; * else if (*(p0+0x00)==0x80 && * *(p0+0x01)==0x3A && * *(p0+0x02)==0x51) * p0type1=1; * * p0type2=0; * if (*(p0+0x09)==0x66 && * *(p0+0x0A)==0xC7 && * *(p0+0x0B)==0x47 && * *(p0+0x0C)==0x08 && * *(p0+0x0D)==0x0C && * *(p0+0x0E)==0x00 && * *(p0+0x0F)==0xE9) * p0type2=0; * else if (*(p0+0x09+3)==0x66 && * *(p0+0x0A+3)==0xC7 && * *(p0+0x0B+3)==0x47 && * *(p0+0x0C+3)==0x08 && * *(p0+0x0D+3)==0x0C && * *(p0+0x0E+3)==0x00 && * *(p0+0x0F+3)==0xE9) * p0type2=1; * * // fix vfp9r.dll * // 0C0B3689: 81E200400000 and edx,000004000 * // 0C0B368F: BE2C000000 mov esi,00000002C * // 0C0B3694: 6A00 push 000 * // 0C0B3696: 81CA00880000 or edx,000008800 * // 0C0B369C: 03C6 add eax,esi * // 0C0B369E: 6A00 push 000 * // 0C0B36A0: C1EA0B shr edx,00B * // 0C0B36A3: 8BCF mov ecx,edi * // 0C0B36A5: A310A2410C mov [00C41A210],eax * // 0C0B36AA: E8EB9F0000 call 00C0BD69A * // 0C0B36AF: 8B0D10A2410C mov ecx,[00C41A210] * // 0C0B36B5: 8B45A0 mov eax,[ebp][-0060] * // 0C0B36B8: 2BCE sub ecx,esi * // 0C0B36BA: 85C0 test eax,eax * // 0C0B36BC: 890D10A2410C mov [00C41A210],ecx * // 0C0B36C2: 750E jne 00C0B36D2 * // 0C0B36C4: A11CC3410C mov eax,[00C41C31C] * // 0C0B36C9: 803851 cmp b,[eax],051 * // 0C0B36CC: 0F8429491200 je 00C1D7FFB * // 0C0B36D2: 66C747080C00 mov w,[edi][00008],0000C * // 0C0B36D8: E995A2F6FF jmp 00C01D972 * * // fix to: * // 0C0B3689: 81E200400000 and edx,000004000 * // 0C0B368F: BE2C000000 mov esi,00000002C * // 0C0B3694: 6A00 push 000 * // 0C0B3696: 81CA00880000 or edx,000008800 * // 0C0B369C: 03C6 add eax,esi * // 0C0B369E: 6A00 push 000 * // 0C0B36A0: C1EA0B shr edx,00B * // 0C0B36A3: 8BCF mov ecx,edi * // 0C0B36A5: A310A2410C mov [00C41A210],eax * // 0C0B36AA: E8EB9F0000 call 00C0BD69A * // 0C0B36AF: 8B0D10A2410C mov ecx,[00C41A210] * // 0C0B36B5: 8B45A0 mov eax,[ebp][-0060] * // 0C0B36B8: 2BCE sub ecx,esi * // 0C0B36BA: 85C0 test eax,eax * // 0C0B36BC: 890D10A2410C mov [00C41A210],ecx * // 0C0B36C2: 750E jne 00C0B36D2 * // 0C0B36C4: A11CC3410C mov eax,[00C41C31C] * // 0C0B36C9: 90 nop * // 0C0B36CA: 90 nop * // 0C0B36CB: 90 nop * // 0C0B36CC: 90 nop * // 0C0B36CD: 90 nop * // 0C0B36CE: 90 nop * // 0C0B36CF: 90 nop * // 0C0B36D0: 90 nop * // 0C0B36D1: 90 nop * // 0C0B36D2: 66C747080C00 mov w,[edi][00008],0000C * // 0C0B36D8: E995A2F6FF jmp 00C01D972 * * // fix vfp9.exe * // 005036AE: 81E100400000 and ecx,000004000 * // 005036B4: 6A00 push 000 * // 005036B6: 81C900880000 or ecx,000008800 * // 005036BC: C74704FFFFFFFF mov d,[edi][00004],0FFFFFFFF * // 005036C3: 8907 mov [edi],eax * // 005036C5: 8B1560719300 mov edx,[000937160] * // 005036CB: 6A00 push 000 * // 005036CD: C1E90B shr ecx,00B * // 005036D0: BE2C000000 mov esi,00000002C * // 005036D5: 51 push ecx * // 005036D6: 03D6 add edx,esi * // 005036D8: 57 push edi * // 005036D9: 891560719300 mov [000937160],edx * // 005036DF: E8C6FEFFFF call 0005035AA * // 005036E4: 8B0D60719300 mov ecx,[000937160] * // 005036EA: 8B45A0 mov eax,[ebp][-0060] * // 005036ED: 2BCE sub ecx,esi * // 005036EF: 85C0 test eax,eax * // 005036F1: 890D60719300 mov [000937160],ecx * // 005036F7: 750F jne 000503708 * // 005036F9: 8B15E0B59300 mov edx,[00093B5E0] * // 005036FF: 803A51 cmp b,[edx],051 * // 00503702: 0F84C9781100 je 00061AFD1 * // 00503708: 8B75B0 mov esi,[ebp][-0050] * // 0050370B: 66C747080C00 mov w,[edi][00008],0000C * // 00503711: E9F5B8F1FF jmp 00041F00B * * // fix to: * // 005036AE: 81E100400000 and ecx,000004000 * // 005036B4: 6A00 push 000 * // 005036B6: 81C900880000 or ecx,000008800 * // 005036BC: C74704FFFFFFFF mov d,[edi][00004],0FFFFFFFF * // 005036C3: 8907 mov [edi],eax * // 005036C5: 8B1560719300 mov edx,[000937160] * // 005036CB: 6A00 push 000 * // 005036CD: C1E90B shr ecx,00B * // 005036D0: BE2C000000 mov esi,00000002C * // 005036D5: 51 push ecx * // 005036D6: 03D6 add edx,esi * // 005036D8: 57 push edi * // 005036D9: 891560719300 mov [000937160],edx * // 005036DF: E8C6FEFFFF call 0005035AA * // 005036E4: 8B0D60719300 mov ecx,[000937160] * // 005036EA: 8B45A0 mov eax,[ebp][-0060] * // 005036ED: 2BCE sub ecx,esi * // 005036EF: 85C0 test eax,eax * // 005036F1: 890D60719300 mov [000937160],ecx * // 005036F7: 750F jne 000503708 * // 005036F9: 8B15E0B59300 mov edx,[00093B5E0] * // 005036FF: 90 nop * // 00503700: 90 nop * // 00503701: 90 nop * // 00503702: 90 nop * // 00503703: 90 nop * // 00503704: 90 nop * // 00503705: 90 nop * // 00503706: 90 nop * // 00503707: 90 nop * // 00503708: 8B75B0 mov esi,[ebp][-0050] * // 0050370B: 66C747080C00 mov w,[edi][00008],0000C * // 00503711: E9F5B8F1FF jmp 00041F00B PRIVATE m.q_str0 m.q_str0=REPL(CHR(0),0x180000-0x080000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000,@m.q_str0,LEN(m.q_str0),0) DO WHILE .T. PRIVATE m.q_p0_nn m.q_p0_nn=1 DO WHILE .T. PRIVATE m.q_p0 m.q_p0=AT(CHR(0x80)+; CHR(0x38)+; CHR(0x51),m.q_str0,m.q_p0_nn) IF !m.q_p0>0 EXIT ENDIF IF !(((SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x38).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51)).OR.; (SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x3a).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51))).AND.; SUBS(m.q_str0,m.q_p0+0x03,1)==CHR(0x0f).AND.; SUBS(m.q_str0,m.q_p0+0x04,1)==CHR(0x84).AND.; ((SUBS(m.q_str0,m.q_p0+0x09,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f,1)==CHR(0xe9)).OR.; (SUBS(m.q_str0,m.q_p0+0x09+3,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a+3,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b+3,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c+3,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d+3,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e+3,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f+3,1)==CHR(0xe9)))) m.q_p0_nn=m.q_p0_nn+1 LOOP ENDIF EXIT ENDDO IF !m.q_p0>0 PRIVATE m.q_p0_nn m.q_p0_nn=1 DO WHILE .T. PRIVATE m.q_p0 m.q_p0=AT(CHR(0x80)+; CHR(0x3a)+; CHR(0x51),m.q_str0,m.q_p0_nn) IF !m.q_p0>0 EXIT ENDIF IF !(((SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x38).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51)).OR.; (SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x3a).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51))).AND.; SUBS(m.q_str0,m.q_p0+0x03,1)==CHR(0x0f).AND.; SUBS(m.q_str0,m.q_p0+0x04,1)==CHR(0x84).AND.; ((SUBS(m.q_str0,m.q_p0+0x09,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f,1)==CHR(0xe9)).OR.; (SUBS(m.q_str0,m.q_p0+0x09+3,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a+3,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b+3,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c+3,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d+3,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e+3,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f+3,1)==CHR(0xe9)))) m.q_p0_nn=m.q_p0_nn+1 LOOP ENDIF EXIT ENDDO ENDIF IF !m.q_p0>0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF PRIVATE m.q_p0type1 m.q_p0type1=0 DO CASE CASE SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x38).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51) m.q_p0type1=0 CASE SUBS(m.q_str0,m.q_p0+0x00,1)==CHR(0x80).AND.; SUBS(m.q_str0,m.q_p0+0x01,1)==CHR(0x3a).AND.; SUBS(m.q_str0,m.q_p0+0x02,1)==CHR(0x51) m.q_p0type1=1 ENDCASE PRIVATE m.q_p0type2 m.q_p0type2=0 DO CASE CASE SUBS(m.q_str0,m.q_p0+0x09,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f,1)==CHR(0xe9) m.q_p0type2=0 CASE SUBS(m.q_str0,m.q_p0+0x09+3,1)==CHR(0x66).AND.; SUBS(m.q_str0,m.q_p0+0x0a+3,1)==CHR(0xc7).AND.; SUBS(m.q_str0,m.q_p0+0x0b+3,1)==CHR(0x47).AND.; SUBS(m.q_str0,m.q_p0+0x0c+3,1)==CHR(0x08).AND.; SUBS(m.q_str0,m.q_p0+0x0d+3,1)==CHR(0x0c).AND.; SUBS(m.q_str0,m.q_p0+0x0e+3,1)==CHR(0x00).AND.; SUBS(m.q_str0,m.q_p0+0x0f+3,1)==CHR(0xe9) m.q_p0type2=1 ENDCASE EXIT ENDDO * for (i=0x000000;i<0x080000;i++) * { * p1=hmodule0+i; * if (*(p1+0x00)==0x83 && * *(p1+0x01)==0xF8 && * *(p1+0x02)==0x18 && * ((*(p1+0x03)==0x77 && * *(p1+0x05)==0x8B && * *(p1+0x06)==0xC8 && * *(p1+0x07)==0xF3 && * *(p1+0x08)==0xA4 && * *(p1+0x09)==0x59 && * *(p1+0x0A)==0x5F && * *(p1+0x0B)==0x5E && * *(p1+0x0C)==0xC2 && * *(p1+0x0D)==0x04 && * *(p1+0x0E)==0x00) || * (*(p1+0x03)==0x0F && * *(p1+0x04)==0x87 && * *(p1+0x05+4)==0x8B && * *(p1+0x06+4)==0xC8 && * *(p1+0x07+4)==0xF3 && * *(p1+0x08+4)==0xA4 && * *(p1+0x09+4)==0x59 && * *(p1+0x0A+4)==0x5F && * *(p1+0x0B+4)==0x5E && * *(p1+0x0C+4)==0xC2 && * *(p1+0x0D+4)==0x04 && * *(p1+0x0E+4)==0x00))) * { * * p1type1=0; * if (*(p1+0x03)==0x77 && * *(p1+0x05)==0x8B && * *(p1+0x06)==0xC8 && * *(p1+0x07)==0xF3 && * *(p1+0x08)==0xA4 && * *(p1+0x09)==0x59 && * *(p1+0x0A)==0x5F && * *(p1+0x0B)==0x5E && * *(p1+0x0C)==0xC2 && * *(p1+0x0D)==0x04 && * *(p1+0x0E)==0x00) * p1type1=0; * else if (*(p1+0x03)==0x0F && * *(p1+0x04)==0x87 && * *(p1+0x05+4)==0x8B && * *(p1+0x06+4)==0xC8 && * *(p1+0x07+4)==0xF3 && * *(p1+0x08+4)==0xA4 && * *(p1+0x09+4)==0x59 && * *(p1+0x0A+4)==0x5F && * *(p1+0x0B+4)==0x5E && * *(p1+0x0C+4)==0xC2 && * *(p1+0x0D+4)==0x04 && * *(p1+0x0E+4)==0x00) * p1type1=1; * * // fix vfp9.exe, vfp9r.dll * // 0C027EF4: 56 push esi * // 0C027EF5: 57 push edi * // 0C027EF6: 8BF9 mov edi,ecx * // 0C027EF8: 8BF2 mov esi,edx * // 0C027EFA: 8B44240C mov eax,[esp][0000C] * // 0C027EFE: 85C0 test eax,eax * // 0C027F00: 0F8CDFD61400 jl 00C1755E5 * // 0C027F06: 8BD7 mov edx,edi * // 0C027F08: 2BD6 sub edx,esi * // 0C027F0A: 3BD0 cmp edx,eax * // 0C027F0C: 0F82B5550000 jb 00C02D4C7 * // 0C027F12: 51 push ecx * // 0C027F13: 8BC8 mov ecx,eax * // 0C027F15: 83F818 cmp eax,018 * // 0C027F18: 770A ja 00C027F24 ;; or 0F870B010000 ja 00C02629D * // 0C027F1A: 8BC8 mov ecx,eax * // 0C027F1C: F3A4 repe movsb * // 0C027F1E: 59 pop ecx * // 0C027F1F: 5F pop edi * // 0C027F20: 5E pop esi * // 0C027F21: C20400 retn 00004 * * // fix to: * // 0C027EF4: 56 push esi * // 0C027EF5: 57 push edi * // 0C027EF6: 8BF9 mov edi,ecx * // 0C027EF8: 8BF2 mov esi,edx * // 0C027EFA: 8B44240C mov eax,[esp][0000C] * // 0C027EFE: 85C0 test eax,eax * // 0C027F00: 0F8CDFD61400 jl 00C1755E5 * // 0C027F06: 8BD7 mov edx,edi * // 0C027F08: 2BD6 sub edx,esi * // 0C027F0A: 3BD0 cmp edx,eax * // 0C027F0C: 0F82B5550000 jb 00C02D4C7 * // 0C027F12: 51 push ecx * // 0C027F13: 8BC8 mov ecx,eax * // 0C027F15: 90 nop * // 0C027F16: 90 nop * // 0C027F17: 90 nop * // 0C027F18: 90 nop * // 0C027F19: 90 nop * // 0C027F1A: 8BC8 mov ecx,eax * // 0C027F1C: F3A4 repe movsb * // 0C027F1E: 59 pop ecx * // 0C027F1F: 5F pop edi * // 0C027F20: 5E pop esi * // 0C027F21: C20400 retn 00004 PRIVATE m.q_str1 m.q_str1=REPL(CHR(0),0x080000-0x000000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x000000,@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(0x83)+; CHR(0xf8)+; CHR(0x18),m.q_str1,m.q_p1_nn) IF !m.q_p1>0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF IF !(SUBS(m.q_str1,m.q_p1+0x00,1)==CHR(0x83).AND.; SUBS(m.q_str1,m.q_p1+0x01,1)==CHR(0xf8).AND.; SUBS(m.q_str1,m.q_p1+0x02,1)==CHR(0x18).AND.; ((SUBS(m.q_str1,m.q_p1+0x03,1)==CHR(0x77).AND.; SUBS(m.q_str1,m.q_p1+0x05,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x06,1)==CHR(0xc8).AND.; SUBS(m.q_str1,m.q_p1+0x07,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x08,1)==CHR(0xa4).AND.; SUBS(m.q_str1,m.q_p1+0x09,1)==CHR(0x59).AND.; SUBS(m.q_str1,m.q_p1+0x0a,1)==CHR(0x5f).AND.; SUBS(m.q_str1,m.q_p1+0x0b,1)==CHR(0x5e).AND.; SUBS(m.q_str1,m.q_p1+0x0c,1)==CHR(0xc2).AND.; SUBS(m.q_str1,m.q_p1+0x0d,1)==CHR(0x04).AND.; SUBS(m.q_str1,m.q_p1+0x0e,1)==CHR(0x00)).OR.; (SUBS(m.q_str1,m.q_p1+0x03,1)==CHR(0x0f).AND.; SUBS(m.q_str1,m.q_p1+0x04,1)==CHR(0x87).AND.; SUBS(m.q_str1,m.q_p1+0x05+4,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x06+4,1)==CHR(0xc8).AND.; SUBS(m.q_str1,m.q_p1+0x07+4,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x08+4,1)==CHR(0xa4).AND.; SUBS(m.q_str1,m.q_p1+0x09+4,1)==CHR(0x59).AND.; SUBS(m.q_str1,m.q_p1+0x0a+4,1)==CHR(0x5f).AND.; SUBS(m.q_str1,m.q_p1+0x0b+4,1)==CHR(0x5e).AND.; SUBS(m.q_str1,m.q_p1+0x0c+4,1)==CHR(0xc2).AND.; SUBS(m.q_str1,m.q_p1+0x0d+4,1)==CHR(0x04).AND.; SUBS(m.q_str1,m.q_p1+0x0e+4,1)==CHR(0x00)))) m.q_p1_nn=m.q_p1_nn+1 LOOP ENDIF PRIVATE m.q_p1type1 m.q_p1type1=0 DO CASE CASE SUBS(m.q_str1,m.q_p1+0x03,1)==CHR(0x77).AND.; SUBS(m.q_str1,m.q_p1+0x05,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x06,1)==CHR(0xc8).AND.; SUBS(m.q_str1,m.q_p1+0x07,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x08,1)==CHR(0xa4).AND.; SUBS(m.q_str1,m.q_p1+0x09,1)==CHR(0x59).AND.; SUBS(m.q_str1,m.q_p1+0x0a,1)==CHR(0x5f).AND.; SUBS(m.q_str1,m.q_p1+0x0b,1)==CHR(0x5e).AND.; SUBS(m.q_str1,m.q_p1+0x0c,1)==CHR(0xc2).AND.; SUBS(m.q_str1,m.q_p1+0x0d,1)==CHR(0x04).AND.; SUBS(m.q_str1,m.q_p1+0x0e,1)==CHR(0x00) m.q_p1type1=0 CASE SUBS(m.q_str1,m.q_p1+0x03,1)==CHR(0x0f).AND.; SUBS(m.q_str1,m.q_p1+0x04,1)==CHR(0x87).AND.; SUBS(m.q_str1,m.q_p1+0x05+4,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x06+4,1)==CHR(0xc8).AND.; SUBS(m.q_str1,m.q_p1+0x07+4,1)==CHR(0xf3).AND.; SUBS(m.q_str1,m.q_p1+0x08+4,1)==CHR(0xa4).AND.; SUBS(m.q_str1,m.q_p1+0x09+4,1)==CHR(0x59).AND.; SUBS(m.q_str1,m.q_p1+0x0a+4,1)==CHR(0x5f).AND.; SUBS(m.q_str1,m.q_p1+0x0b+4,1)==CHR(0x5e).AND.; SUBS(m.q_str1,m.q_p1+0x0c+4,1)==CHR(0xc2).AND.; SUBS(m.q_str1,m.q_p1+0x0d+4,1)==CHR(0x04).AND.; SUBS(m.q_str1,m.q_p1+0x0e+4,1)==CHR(0x00) m.q_p1type1=1 ENDCASE EXIT ENDDO * for (i=0x000000;i<0x080000;i++) * { * p2=hmodule0+i; * if (*(p2+0x00)==0x33 && * *(p2+0x01)==0xC9 && * *(p2+0x02)==0x2B && * *(p2+0x03)==0xCF && * *(p2+0x04)==0x83 && * *(p2+0x05)==0xE1 && * *(p2+0x06)==0x03 && * *(p2+0x07)==0x2B && * *(p2+0x08)==0xC1 && * *(p2+0x09)==0xF3 && * *(p2+0x0A)==0xA4 && * *(p2+0x0B)==0x8B && * *(p2+0x0C)==0xC8 && * *(p2+0x0D)==0xC1 && * *(p2+0x0E)==0xE9 && * *(p2+0x0F)==0x02 && * *(p2+0x10)==0xF3 && * *(p2+0x11)==0xA5 && * *(p2+0x12)==0x83 && * *(p2+0x13)==0xE0 && * *(p2+0x14)==0x03 && * ((*(p2+0x15)==0xEB) || * (*(p2+0x15)==0xE9))) * { * * p2type1=0; * if (*(p2+0x15)==0xEB) * p2type1=0; * else if (*(p2+0x15)==0xE9) * p2type1=1; * * // fix vfp9.exe, vfp9r.dll * // 0C027F24: 33C9 xor ecx,ecx * // 0C027F26: 2BCF sub ecx,edi * // 0C027F28: 83E103 and ecx,003 * // 0C027F2B: 2BC1 sub eax,ecx * // 0C027F2D: F3A4 repe movsb * // 0C027F2F: 8BC8 mov ecx,eax * // 0C027F31: C1E902 shr ecx,002 * // 0C027F34: F3A5 repe movsd * // 0C027F36: 83E003 and eax,003 * // 0C027F39: EBDF jmps 00C027F1A ;; or E9DBFEFFFF jmp 00C026192 * * // fix to: * // 0C027F24 807C33 FA 00 CMP BYTE PTR DS:[EBX+ESI-6],0 ;; or 807C3E FA 00 CMP BYTE PTR DS:[EDI+ESI-6],0 * // 0C027F29 74 04 JE SHORT vfp9r.0C027F2F * // 0C027F2B 6A 05 PUSH 5 * // 0C027F2D EB 02 JMP SHORT vfp9r.0C027F31 * // 0C027F2F 6A 07 PUSH 7 * // 0C027F31 2B3424 SUB ESI,DWORD PTR SS:[ESP] * // 0C027F34 E9 30CA1400 JMP vfp9r.0C174969 * // 0C027F39 90 NOP * // 0C027F3A 90 NOP PRIVATE m.q_str2 m.q_str2=REPL(CHR(0),0x080000-0x000000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x000000,@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(0x33)+; CHR(0xc9)+; CHR(0x2b)+; CHR(0xcf)+; CHR(0x83)+; CHR(0xe1)+; CHR(0x03)+; CHR(0x2b)+; CHR(0xc1)+; CHR(0xf3)+; CHR(0xa4)+; CHR(0x8b)+; CHR(0xc8)+; CHR(0xc1)+; CHR(0xe9)+; CHR(0x02)+; CHR(0xf3)+; CHR(0xa5)+; CHR(0x83)+; CHR(0xe0)+; CHR(0x03),m.q_str2,m.q_p2_nn) IF !m.q_p2>0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF IF !(SUBS(m.q_str2,m.q_p2+0x00,1)==CHR(0x33).AND.; SUBS(m.q_str2,m.q_p2+0x01,1)==CHR(0xc9).AND.; SUBS(m.q_str2,m.q_p2+0x02,1)==CHR(0x2b).AND.; SUBS(m.q_str2,m.q_p2+0x03,1)==CHR(0xcf).AND.; SUBS(m.q_str2,m.q_p2+0x04,1)==CHR(0x83).AND.; SUBS(m.q_str2,m.q_p2+0x05,1)==CHR(0xe1).AND.; SUBS(m.q_str2,m.q_p2+0x06,1)==CHR(0x03).AND.; SUBS(m.q_str2,m.q_p2+0x07,1)==CHR(0x2b).AND.; SUBS(m.q_str2,m.q_p2+0x08,1)==CHR(0xc1).AND.; SUBS(m.q_str2,m.q_p2+0x09,1)==CHR(0xf3).AND.; SUBS(m.q_str2,m.q_p2+0x0a,1)==CHR(0xa4).AND.; SUBS(m.q_str2,m.q_p2+0x0b,1)==CHR(0x8b).AND.; SUBS(m.q_str2,m.q_p2+0x0c,1)==CHR(0xc8).AND.; SUBS(m.q_str2,m.q_p2+0x0d,1)==CHR(0xc1).AND.; SUBS(m.q_str2,m.q_p2+0x0e,1)==CHR(0xe9).AND.; SUBS(m.q_str2,m.q_p2+0x0f,1)==CHR(0x02).AND.; SUBS(m.q_str2,m.q_p2+0x10,1)==CHR(0xf3).AND.; SUBS(m.q_str2,m.q_p2+0x11,1)==CHR(0xa5).AND.; SUBS(m.q_str2,m.q_p2+0x12,1)==CHR(0x83).AND.; SUBS(m.q_str2,m.q_p2+0x13,1)==CHR(0xe0).AND.; SUBS(m.q_str2,m.q_p2+0x14,1)==CHR(0x03).AND.; ((SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0xeb)).OR.; (SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0xe9)))) m.q_p2_nn=m.q_p2_nn+1 LOOP ENDIF PRIVATE m.q_p2type1 m.q_p2type1=0 DO CASE CASE SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0xeb) m.q_p2type1=0 CASE SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0xe9) m.q_p2type1=1 ENDCASE EXIT ENDDO * for (i=0x080000;i<0x200000;i++) * { * p3=hmodule0+i; * if (*(p3+0x00)==0x83 && * *(p3+0x01)==0xEE && * *(p3+0x02)==0x05 && * ((*(p3+0x03)==0x8D && * *(p3+0x04)==0x3C && * *(p3+0x05)==0x1E && * *(p3+0x06)==0x6A && * *(p3+0x07)==0x05 && * *(p3+0x08)==0x8B && * *(p3+0x09)==0xD7) || * (*(p3+0x03)==0x8D && * *(p3+0x04)==0x1C && * *(p3+0x05)==0x37 && * *(p3+0x06)==0x6A && * *(p3+0x07)==0x05 && * *(p3+0x08)==0x8B && * *(p3+0x09)==0xD3))) * { * * p3type1=0; * if (*(p3+0x03)==0x8D && * *(p3+0x04)==0x3C && * *(p3+0x05)==0x1E && * *(p3+0x06)==0x6A && * *(p3+0x07)==0x05 && * *(p3+0x08)==0x8B && * *(p3+0x09)==0xD7) * p3type1=0; * else if (*(p3+0x03)==0x8D && * *(p3+0x04)==0x1C && * *(p3+0x05)==0x37 && * *(p3+0x06)==0x6A && * *(p3+0x07)==0x05 && * *(p3+0x08)==0x8B && * *(p3+0x09)==0xD3) * p3type1=1; * * // fix vfp9.exe, vfp9r.dll * // 0C174964: 83EE05 sub esi,005 * // 0C174967: 8D3C1E lea edi,[esi][ebx] ;; or 8D1C37 lea ebx,[edi][esi] * // 0C17496A: 6A05 push 005 * // 0C17496C: 8BD7 mov edx,edi ;; or 8BD3 mov edx,ebx * // 0C17496E: 8D4DF0 lea ecx,[ebp][-0010] * // 0C174971: E87E35EBFF call 00C027EF4 * // 0C174976: C60700 mov b,[edi],000 * // 0C174979: 46 inc esi * // 0C17497A: E981ABF1FF jmp 00C08F500 * * // fix to: * // 0C174964 E9 BB35EBFF JMP vfp9r.0C027F24 * // 0C174969 8D3C1E LEA EDI,DWORD PTR DS:[ESI+EBX] ;; or 8D1C37 lea ebx,[edi][esi] * // 0C17496C 8BD7 MOV EDX,EDI ;; or 8BD3 mov edx,ebx * // 0C17496E 8D4D F0 LEA ECX,DWORD PTR SS:[EBP-10] * // 0C174971 E8 7E35EBFF CALL vfp9r.0C027EF4 * // 0C174976 C607 00 MOV BYTE PTR DS:[EDI],0 * // 0C174979 46 INC ESI * // 0C17497A E9 81ABF1FF JMP vfp9r.0C08F500 PRIVATE m.q_str3 m.q_str3=REPL(CHR(0),0x200000-0x080000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000,@m.q_str3,LEN(m.q_str3),0) PRIVATE m.q_p3_nn m.q_p3_nn=1 DO WHILE .T. PRIVATE m.q_p3 m.q_p3=AT(CHR(0x83)+; CHR(0xee)+; CHR(0x05),m.q_str3,m.q_p3_nn) IF !m.q_p3>0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF IF !(SUBS(m.q_str3,m.q_p3+0x00,1)==CHR(0x83).AND.; SUBS(m.q_str3,m.q_p3+0x01,1)==CHR(0xee).AND.; SUBS(m.q_str3,m.q_p3+0x02,1)==CHR(0x05).AND.; ((SUBS(m.q_str3,m.q_p3+0x03,1)==CHR(0x8d).AND.; SUBS(m.q_str3,m.q_p3+0x04,1)==CHR(0x3c).AND.; SUBS(m.q_str3,m.q_p3+0x05,1)==CHR(0x1e).AND.; SUBS(m.q_str3,m.q_p3+0x06,1)==CHR(0x6a).AND.; SUBS(m.q_str3,m.q_p3+0x07,1)==CHR(0x05).AND.; SUBS(m.q_str3,m.q_p3+0x08,1)==CHR(0x8b).AND.; SUBS(m.q_str3,m.q_p3+0x09,1)==CHR(0xd7)).OR.; (SUBS(m.q_str3,m.q_p3+0x03,1)==CHR(0x8d).AND.; SUBS(m.q_str3,m.q_p3+0x04,1)==CHR(0x1c).AND.; SUBS(m.q_str3,m.q_p3+0x05,1)==CHR(0x37).AND.; SUBS(m.q_str3,m.q_p3+0x06,1)==CHR(0x6a).AND.; SUBS(m.q_str3,m.q_p3+0x07,1)==CHR(0x05).AND.; SUBS(m.q_str3,m.q_p3+0x08,1)==CHR(0x8b).AND.; SUBS(m.q_str3,m.q_p3+0x09,1)==CHR(0xd3)))) m.q_p3_nn=m.q_p3_nn+1 LOOP ENDIF PRIVATE m.q_p3type1 m.q_p3type1=0 DO CASE CASE SUBS(m.q_str3,m.q_p3+0x03,1)==CHR(0x8d).AND.; SUBS(m.q_str3,m.q_p3+0x04,1)==CHR(0x3c).AND.; SUBS(m.q_str3,m.q_p3+0x05,1)==CHR(0x1e).AND.; SUBS(m.q_str3,m.q_p3+0x06,1)==CHR(0x6a).AND.; SUBS(m.q_str3,m.q_p3+0x07,1)==CHR(0x05).AND.; SUBS(m.q_str3,m.q_p3+0x08,1)==CHR(0x8b).AND.; SUBS(m.q_str3,m.q_p3+0x09,1)==CHR(0xd7) m.q_p3type1=0 CASE SUBS(m.q_str3,m.q_p3+0x03,1)==CHR(0x8d).AND.; SUBS(m.q_str3,m.q_p3+0x04,1)==CHR(0x1c).AND.; SUBS(m.q_str3,m.q_p3+0x05,1)==CHR(0x37).AND.; SUBS(m.q_str3,m.q_p3+0x06,1)==CHR(0x6a).AND.; SUBS(m.q_str3,m.q_p3+0x07,1)==CHR(0x05).AND.; SUBS(m.q_str3,m.q_p3+0x08,1)==CHR(0x8b).AND.; SUBS(m.q_str3,m.q_p3+0x09,1)==CHR(0xd3) m.q_p3type1=1 ENDCASE EXIT ENDDO * for (i=0x080000;i<0x200000;i++) * { * p4=hmodule0+i; * if (*(p4+0x00)==0x6A && * *(p4+0x01)==0x04 && * *(p4+0x02)==0x8D && * *(p4+0x03)==0x55 && * *(p4+0x04)==0xF0 && * *(p4+0x05)==0xE8 && * ((*(p4+0x0A)==0x8D && * *(p4+0x0B)==0x47 && * *(p4+0x0C)==0x03) || * (*(p4+0x0A)==0x8D && * *(p4+0x0B)==0x46 && * *(p4+0x0C)==0x03)) && * *(p4+0x0D)==0xE9) * { * * p4type1=0; * if (*(p4+0x0A)==0x8D && * *(p4+0x0B)==0x47 && * *(p4+0x0C)==0x03) * p4type1=0; * else if (*(p4+0x0A)==0x8D && * *(p4+0x0B)==0x46 && * *(p4+0x0C)==0x03) * p4type1=1; * * // fix vfp9.exe, vfp9r.dll * // 0C1749EF: 8B1588C2410C mov edx,[00C41C288] * // 0C1749F5: 8D4C3AFF lea ecx,[edx][edi][-0001] ;; or 8D4C32FF lea ecx,[edx][esi][-0001] * // 0C1749F9: 6A04 push 004 * // 0C1749FB: 8D55F0 lea edx,[ebp][-0010] * // 0C1749FE: E8F134EBFF call 00C027EF4 * // 0C174A03: 8D4703 lea eax,[edi][00003] ;; or 8D4603 lea eax,[esi][00003] * // 0C174A06: E9D2ABF1FF jmp 00C08F5DD * * // fix to: * // 0C1749EF: 8B1588C2410C mov edx,[00C41C288] * // 0C1749F5: 8D4C3AFF lea ecx,[edx][edi][-0001] ;; or 8D4C32FF lea ecx,[edx][esi][-0001] * // 0C1749F9: 6A06 push 006 * // 0C1749FB: 8D55F0 lea edx,[ebp][-0010] * // 0C1749FE: E8F134EBFF call 00C027EF4 * // 0C174A03: 8D4705 lea eax,[edi][00005] ;; or 8D4605 lea eax,[esi][00005] * // 0C174A06: E9D2ABF1FF jmp 00C08F5DD PRIVATE m.q_str4 m.q_str4=REPL(CHR(0),0x200000-0x080000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000,@m.q_str4,LEN(m.q_str4),0) PRIVATE m.q_p4_nn m.q_p4_nn=1 DO WHILE .T. PRIVATE m.q_p4 m.q_p4=AT(CHR(0x6a)+; CHR(0x04)+; CHR(0x8d)+; CHR(0x55)+; CHR(0xf0)+; CHR(0xe8),m.q_str4,m.q_p4_nn) IF !m.q_p4>0 m.q_vfp9fixmacrosubstitution=.F. RETU m.q_vfp9fixmacrosubstitution ENDIF IF !(SUBS(m.q_str4,m.q_p4+0x00,1)==CHR(0x6a).AND.; SUBS(m.q_str4,m.q_p4+0x01,1)==CHR(0x04).AND.; SUBS(m.q_str4,m.q_p4+0x02,1)==CHR(0x8d).AND.; SUBS(m.q_str4,m.q_p4+0x03,1)==CHR(0x55).AND.; SUBS(m.q_str4,m.q_p4+0x04,1)==CHR(0xf0).AND.; SUBS(m.q_str4,m.q_p4+0x05,1)==CHR(0xe8).AND.; ((SUBS(m.q_str4,m.q_p4+0x0a,1)==CHR(0x8d).AND.; SUBS(m.q_str4,m.q_p4+0x0b,1)==CHR(0x47).AND.; SUBS(m.q_str4,m.q_p4+0x0c,1)==CHR(0x03)).OR.; (SUBS(m.q_str4,m.q_p4+0x0a,1)==CHR(0x8d).AND.; SUBS(m.q_str4,m.q_p4+0x0b,1)==CHR(0x46).AND.; SUBS(m.q_str4,m.q_p4+0x0c,1)==CHR(0x03))).AND.; SUBS(m.q_str4,m.q_p4+0x0d,1)==CHR(0xe9)) m.q_p4_nn=m.q_p4_nn+1 LOOP ENDIF PRIVATE m.q_p4type1 m.q_p4type1=0 DO CASE CASE SUBS(m.q_str4,m.q_p4+0x0a,1)==CHR(0x8d).AND.; SUBS(m.q_str4,m.q_p4+0x0b,1)==CHR(0x47).AND.; SUBS(m.q_str4,m.q_p4+0x0c,1)==CHR(0x03) m.q_p4type1=0 CASE SUBS(m.q_str4,m.q_p4+0x0a,1)==CHR(0x8d).AND.; SUBS(m.q_str4,m.q_p4+0x0b,1)==CHR(0x46).AND.; SUBS(m.q_str4,m.q_p4+0x0c,1)==CHR(0x03) m.q_p4type1=1 ENDCASE EXIT ENDDO * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p0,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p0+0x00)=0x90; * *(p0+0x01)=0x90; * *(p0+0x02)=0x90; * *(p0+0x03)=0x90; * *(p0+0x04)=0x90; * *(p0+0x05)=0x90; * *(p0+0x06)=0x90; * *(p0+0x07)=0x90; * *(p0+0x08)=0x90; * VirtualProtect(p0,0x10,OldProtect,&OldProtect); * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p1,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * if (p1type1==0) * { * *(p1+0x00)=0x90; * *(p1+0x01)=0x90; * *(p1+0x02)=0x90; * *(p1+0x03)=0x90; * *(p1+0x04)=0x90; * } * else * { * *(p1+0x00)=0x90; * *(p1+0x01)=0x90; * *(p1+0x02)=0x90; * *(p1+0x03)=0x90; * *(p1+0x04)=0x90; * *(p1+0x05)=0x90; * *(p1+0x06)=0x90; * *(p1+0x07)=0x90; * *(p1+0x08)=0x90; * } * VirtualProtect(p1,0x10,OldProtect,&OldProtect); * * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p2,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * if (p3type1==0) * { * *(p2+0x00)=0x80; * *(p2+0x01)=0x7C; * *(p2+0x02)=0x33; * *(p2+0x03)=0xFA; * *(p2+0x04)=0x00; * } * else * { * *(p2+0x00)=0x80; * *(p2+0x01)=0x7C; * *(p2+0x02)=0x3E; * *(p2+0x03)=0xFA; * *(p2+0x04)=0x00; * } * *(p2+0x05)=0x74; * *(p2+0x06)=0x04; * *(p2+0x07)=0x6A; * *(p2+0x08)=0x05; * *(p2+0x09)=0xEB; * *(p2+0x0A)=0x02; * *(p2+0x0B)=0x6A; * *(p2+0x0C)=0x07; * *(p2+0x0D)=0x2B; * *(p2+0x0E)=0x34; * *(p2+0x0F)=0x24; * *(p2+0x10)=0xE9; * p2int=p2+0x11; * *(p2int)=(p3+0x05)-(p2+0x10+5); * if (p2type1==0) * { * *(p2+0x15)=0x90; * *(p2+0x16)=0x90; * } * else * { * *(p2+0x15)=0x90; * *(p2+0x16)=0x90; * *(p2+0x17)=0x90; * *(p2+0x18)=0x90; * *(p2+0x19)=0x90; * } * VirtualProtect(p2,0x20,OldProtect,&OldProtect); * * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p3,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p3+0x00)=0xE9; * p3int=p3+0x01; * *(p3int)=(p2+0x00)-(p3+0x00+5); * if (p3type1==0) * { * *(p3+0x05)=0x8D; * *(p3+0x06)=0x3C; * *(p3+0x07)=0x1E; * } * else * { * *(p3+0x05)=0x8D; * *(p3+0x06)=0x1C; * *(p3+0x07)=0x37; * } * VirtualProtect(p3,0x10,OldProtect,&OldProtect); * * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p4,0x10,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p4+0x01)=0x06; * *(p4+0x0C)=0x05; * VirtualProtect(p4,0x10,OldProtect,&OldProtect); PRIVATE m.q_str0 m.q_str0=CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90) IF m.q_p1type1=0 PRIVATE m.q_str1 m.q_str1=CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90) ELSE PRIVATE m.q_str1 m.q_str1=CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90) ENDIF IF m.q_p3type1=0 PRIVATE m.q_str2 m.q_str2=CHR(0x80)+; CHR(0x7c)+; CHR(0x33)+; CHR(0xfa)+; CHR(0x00) ELSE PRIVATE m.q_str2 m.q_str2=CHR(0x80)+; CHR(0x7c)+; CHR(0x3e)+; CHR(0xfa)+; CHR(0x00) ENDIF m.q_str2=m.q_str2+CHR(0x74)+; CHR(0x04)+; CHR(0x6a)+; CHR(0x05)+; CHR(0xeb)+; CHR(0x02)+; CHR(0x6a)+; CHR(0x07)+; CHR(0x2b)+; CHR(0x34)+; CHR(0x24)+; CHR(0xe9)+; CHR(MOD(((m.q_hmodule0+0x080000+m.q_p3+0x05)-(m.q_hmodule0+0x000000+m.q_p2+0x10+5)),256))+; CHR(MOD(INT(((m.q_hmodule0+0x080000+m.q_p3+0x05)-(m.q_hmodule0+0x000000+m.q_p2+0x10+5))/256),256))+; CHR(MOD(INT(((m.q_hmodule0+0x080000+m.q_p3+0x05)-(m.q_hmodule0+0x000000+m.q_p2+0x10+5))/(256*256)),256))+; CHR(MOD(INT(((m.q_hmodule0+0x080000+m.q_p3+0x05)-(m.q_hmodule0+0x000000+m.q_p2+0x10+5))/(256*256*256)),256)) IF m.q_p2type1=0 m.q_str2=m.q_str2+CHR(0x90)+; CHR(0x90) ELSE m.q_str2=m.q_str2+CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90)+; CHR(0x90) ENDIF PRIVATE m.q_str3 m.q_str3=CHR(0xe9)+; CHR(MOD(((m.q_hmodule0+0x000000+m.q_p2+0x00)-(m.q_hmodule0+0x080000+m.q_p3+0x00+5)+0x100000000),256))+; CHR(MOD(INT(((m.q_hmodule0+0x000000+m.q_p2+0x00)-(m.q_hmodule0+0x080000+m.q_p3+0x00+5)+0x100000000)/256),256))+; CHR(MOD(INT(((m.q_hmodule0+0x000000+m.q_p2+0x00)-(m.q_hmodule0+0x080000+m.q_p3+0x00+5)+0x100000000)/(256*256)),256))+; CHR(MOD(INT(((m.q_hmodule0+0x000000+m.q_p2+0x00)-(m.q_hmodule0+0x080000+m.q_p3+0x00+5)+0x100000000)/(256*256*256)),256)) IF m.q_p3type1=0 m.q_str3=m.q_str3+CHR(0x8d)+; CHR(0x3c)+; CHR(0x1e) ELSE PRIVATE m.q_str3 m.q_str3=m.q_str3+CHR(0x8d)+; CHR(0x1c)+; CHR(0x37) ENDIF PRIVATE m.q_str4 m.q_str4=REPL(CHR(0),0x10) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p4-1+0x00,@m.q_str4,LEN(m.q_str4),0) m.q_str4=STUFF(m.q_str4,0x01+1,1,CHR(0x06)) m.q_str4=STUFF(m.q_str4,0x0c+1,1,CHR(0x05)) PRIVATE m.q_oldprotect0 m.q_oldprotect0=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x080000+m.q_p0-1,0x10,0x40,@m.q_oldprotect0) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect1 m.q_oldprotect1=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x000000+m.q_p1-1,0x10,0x40,@m.q_oldprotect1) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect2 m.q_oldprotect2=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x000000+m.q_p2-1,0x20,0x40,@m.q_oldprotect2) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect3 m.q_oldprotect3=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x080000+m.q_p3-1,0x10,0x40,@m.q_oldprotect3) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect4 m.q_oldprotect4=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x080000+m.q_p4-1,0x10,0x40,@m.q_oldprotect4) && PAGE_EXECUTE_READWRITE =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p0-1+0x00,m.q_str0,LEN(m.q_str0),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x000000+m.q_p1-1+0x00,m.q_str1,LEN(m.q_str1),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x000000+m.q_p2-1+0x00,m.q_str2,LEN(m.q_str2),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p3-1+0x00,m.q_str3,LEN(m.q_str3),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p4-1+0x00,m.q_str4,LEN(m.q_str4),0) =virtualprotect(m.q_hmodule0+0x080000+m.q_p0-1,0x10,m.q_oldprotect0,@m.q_oldprotect0) =virtualprotect(m.q_hmodule0+0x000000+m.q_p1-1,0x10,m.q_oldprotect1,@m.q_oldprotect1) =virtualprotect(m.q_hmodule0+0x000000+m.q_p2-1,0x20,m.q_oldprotect2,@m.q_oldprotect2) =virtualprotect(m.q_hmodule0+0x080000+m.q_p3-1,0x10,m.q_oldprotect3,@m.q_oldprotect3) =virtualprotect(m.q_hmodule0+0x080000+m.q_p4-1,0x10,m.q_oldprotect4,@m.q_oldprotect4) m.q_vfp9fixmacrosubstitution=.T. RETU m.q_vfp9fixmacrosubstitution * END OF PROC F_VFP9FIXMACROSUBSTITUTION. 6, Recommend to add the following code to the start program: * VFP9FixMacroSubstitution #IF ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 =f_vfp9fixmacrosubstitution() #ENDI Now in vfp9, the large program can run correctly too. 4. APPLIES TO: 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_vfp9fix157.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix158.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix241.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix242.asp 2, foxite.com: http://www.foxite.com/archives/vfp-9-errors-on-valid-programming-statem-0000240109.htm http://www.foxite.com/archives/vfp-90-fix-macro-substitution-0000250329.htm http://www.foxite.com/archives/problems-with-macro-substitution-0000286226.htm 3, Calvin Hsia's WebLog: http://blogs.msdn.com/b/calvin_hsia/archive/2006/04/04/568461.aspx 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |