Foxpro App File Structure
Foxpro App File Structure
asp
-----------------------------------------------
FOXPRO APP FILE STRUCTURE (UNDOCUMENTED)
January 2013
-----------------------------------------------
CCB
00-07 DB "fox.prg",0
08-10 DB "c:\temp\",0
11-18 DB "fox.fxp",0
19-1B DB ".\",0
1C-23 DB "fox.scx",0
24-2B DB "fox.sct",0
2C-33 DB "fox.frx",0
34-3B DB "fox.frt",0
3. File type:
00: program file, include program file .PRG/.FXP, format file .FMT/.PRX,
screen file .SPR/.SPX, menu file .MPR/.MPX, query file .QPR/.QPX
02: table file, include database file .DBC, table file .DBF
03: memo file, include memo file .FPT, class memo file .VCT, form memo file .SCT,
report memo file .FRT, label memo file .LBT
04: compound index file .CDX
05: compact index file .IDX
06: text file .TXT
07: api library file .FLL
08: class file .VCX
09: form file .SCX
0A: report file .FRX
0B: label file .LBX
Total 5 files:
1) fox.fxp:
2) fox.scx:
00002290: 09 47 ..
000022A0: 01 00 00 04-07 00 00 19-00 00 00 1C-00 00 00 00 ................
000022B0: 00 00 00 00-00 00 00 .......
3) fox.sct:
4) fox.frx:
00000A50: 30 09 04 03 ............0...
00000A60: 06 00 00 00-88 0A E5 00-00 00 00 00-00 00 00 00 ................
00000A70: 00 00 00 00-00 00 00 00-02 7A 00 00-50 4C 41 54 ............PLAT
00000A80: 46 4F 52 4D-00 00 00 43-01 00 00 00-08 00 00 00 FORM...C........
00000A90: 00 00 00 00-00 00 00 00-00 00 00 00-55 4E 49 51 ............UNIQ
00000AA0: 55 45 49 44-00 00 00 43-09 00 00 00-0A 00 00 00 UEID...C........
00000AB0: 00 00 00 00-00 00 00 00-00 00 00 00-54 49 4D 45 ............TIME
00000AC0: 53 54 41 4D-50 00 00 4E-13 00 00 00-0A 00 00 00 STAMP..N........
............................................................................
00001A20: 20 20 20 20-20 20 20 20-20 20 20 20-20 20 20 20 ................
00001A30: 20 20 20 20-20 20 20 20-20 20 00 00-00 00 00 00 ................
00001A40: 00 00 1A ...
5) fox.frt:
0) fox.fxp:
Total 2 procedures:
00000070: 08 00 ..
00000080: 70 72 6F 63-5F 66 6F 78-3F 00 00 00-00 00 FF FF proc_fox........
00000090: 04 00 49 4E-49 54 5E 00-00 00 01 00-00 00 ..INIT........
1) procedure proc_fox:
00000070: 08 00 ..
00000080: 70 72 6F 63-5F 66 6F 78-3F 00 00 00-00 00 FF FF proc_fox........
00000030: 17 .fox............
00000040: 00 10 00 54-F7 00 00 10-FC D9 03 00-66 6F 78 FD ............fox.
00000050: FE 04 00 52-FE 03 00 55-01 00 02 00-58 31 ............X1
2) procedure INIT:
00000050: 18 00 ................
00000060: 11 00 54 F7-00 00 10 FC-D9 04 00 66-6F 78 32 FD ................
00000070: FE 04 00 52-FE 03 00 55-01 00 02 00-58 32 ............X2
Before vfp9, procedure size <64K, use one WORD can save the size of procedure:
00-01 DW size of procedure
In vfp9, procedure size >64K possible, use one WORD and one DWORD to save the size of procedure:
00-01 DW 0
02-05 DD size of procedure
Total 1 class:
000000A0: 09 .
000000B0: 00 63 6C 61-73 73 5F 66-6F 78 06 00-43 55 53 54 .class_fox..CUST
000000C0: 4F 4D 9E 00-00 00 00 00 OM.......
00000090: 0D 00 ..
000000A0: 0A 00 A2 E9-00 02 00 00-00 FE 03 00-55 00 00 ...............
Total (1+2+1)*4 DWORDs, four DWORDs for per fxp, procedures, classes.
000000D0: 00 00 ..
000000E0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 03 00 ................
000000F0: 00 00 1D 00-00 00 2B 00-00 00 03 00-00 00 06 00 ................
00000100: 00 00 5A 00-00 00 69 00-00 00 07 00-00 00 09 00 ................
00000110: 00 00 4F 00-00 00 69 00-00 00 06 00-00 00 ..............
*PROC papp_sum
PARAMETER m.q_str
* m.q_str =
* PARAMETER: String
* RETURN: Checksum
PRIVATE m.q_nn
PRIVATE m.q_sum
PRIVATE m.q_suma
PRIVATE m.q_suma1
PRIVATE m.q_suma2
PRIVATE m.q_sumb
PRIVATE m.q_sumb1
PRIVATE m.q_sumb2
PRIVATE m.q_sumc
PRIVATE m.q_sumc1
PRIVATE m.q_sumc2
PRIVATE m.q_sumd
PRIVATE m.q_sumd1
PRIVATE m.q_sumd2
PRIVATE m.q_sume
PRIVATE m.q_sumf
*
* FoxPro Application File (.APP) Checksum
* 1998.05.01 Write by CCB
*
* Crack with Soft-ice
*
* ASM CODE:
*
* code segment
*
* assume cs:code,ds:code,es:code
*
* org 100h
*
* start:
*
* jmp begin
*
* head_25 db 0feh,0f2h,0ffh,0ffh,0ch,02h
* head_30 db 0feh,0f2h,0ffh,1bh,02h
* head_50 db 0feh,0f2h,0ffh,1fh,02h
*
* head db 0feh,0f2h,0ffh,0ffh,0ch,02h
* dw 00a0h
* dw 0001h
* dd 1430h
* dd 0430h
* dd 1000h
* db 18 dup(0)
* head_len = $ - (offset head)
* head_sum dw ? ; 71f6h / 8d11h / ddc7h
*
* begin:
*
* push cs
* pop ds
*
* mov ah,byte ptr head[0]
* mov al,byte ptr head[1]
*
* mov si,0
*
* mov bx,head_len-2
*
* s_loop:
*
* cmp bx,0
* jz s_save
*
* mov dl,ah
* mov dh,al
* mov al,byte ptr head[si]
* xor ah,ah
* xor ax,dx
* mov dx,ax
* mov cl,4
* xor dh,ah
* shr dx,cl
* xor ax,dx
* mov dx,ax
* xor dh,ah
* xor cl,cl
* mov ch,al
* mov di,0
* add di,cx
* mov cl,4
* shl di,cl
* mov cl,5
* xor ax,di
* shl dx,cl
* xor ax,dx
* inc si
* dec bx
* jmp s_loop
*
* s_save:
*
* mov head_sum,ax
*
* mov ax,4c00h
* int 21h
*
* code ends
*
* end start
*
*
* AX head[si]
* ----------------- ---------
* | a | b | c | d | | e | f |
* ----------------- ---------
*
* AX DX
* ------------------ -----------------
* | c | d | a | a | | 0 | a | a | 0 |
* | a | | e | b | | | e | b | |
* | b | | | e | | | | e | |
* | e | | | f | | | | f | |
* | f | | | | | | | | |
* --|-------|---|--- ------|---|------
* XOR XOR XOR XOR XOR
*
* (AX) = (AX) XOR (DX)*2
*
* FOXPRO CODE:
*
m.q_sum=ASC(SUBS(m.q_str,1,1))*256+ASC(SUBS(m.q_str,2,1))
m.q_suma=INT(MOD(m.q_sum,16^4)/16^3)
m.q_sumb=INT(MOD(m.q_sum,16^3)/16^2)
m.q_sumc=INT(MOD(m.q_sum,16^2)/16^1)
m.q_sumd=INT(MOD(m.q_sum,16^1)/16^0)
m.q_nn=1
DO WHILE m.q_nn<=LEN(m.q_str)-2
m.q_sum=ASC(SUBS(m.q_str,m.q_nn,1))
m.q_sume=INT(MOD(m.q_sum,16^2)/16^1)
m.q_sumf=INT(MOD(m.q_sum,16^1)/16^0)
m.q_suma2=0
m.q_sumb2=fbin_xor(m.q_suma,m.q_sume)
m.q_sumc2=fbin_xor(fbin_xor(fbin_xor(m.q_suma,m.q_sumb),m.q_sume),m.q_sumf)
m.q_sumd2=0
m.q_sum=m.q_suma2*16^3+m.q_sumb2*16^2+m.q_sumc2*16^1+m.q_sumd2*16^0
m.q_sum=m.q_sum*2
m.q_suma2=INT(MOD(m.q_sum,16^4)/16^3)
m.q_sumb2=INT(MOD(m.q_sum,16^3)/16^2)
m.q_sumc2=INT(MOD(m.q_sum,16^2)/16^1)
m.q_sumd2=INT(MOD(m.q_sum,16^1)/16^0)
m.q_suma1=fbin_xor(fbin_xor(fbin_xor(fbin_xor(m.q_sumc,m.q_suma),m.q_sumb),m.q_sume),m.q_sumf)
m.q_sumb1=m.q_sumd
m.q_sumc1=fbin_xor(m.q_suma,m.q_sume)
m.q_sumd1=fbin_xor(fbin_xor(fbin_xor(m.q_suma,m.q_sumb),m.q_sume),m.q_sumf)
m.q_suma=fbin_xor(m.q_suma1,m.q_suma2)
m.q_sumb=fbin_xor(m.q_sumb1,m.q_sumb2)
m.q_sumc=fbin_xor(m.q_sumc1,m.q_sumc2)
m.q_sumd=fbin_xor(m.q_sumd1,m.q_sumd2)
m.q_nn=m.q_nn+1
ENDDO
RETU CHR(m.q_sumc*16+m.q_sumd)+CHR(m.q_suma*16+m.q_sumb)
FUNCTION fbin_xor
PARAMETER m.q_a,m.q_b
* m.q_a =
* m.q_b =
RETU IIF(INT(MOD(m.q_a,16)/8)#INT(MOD(m.q_b,16)/8),1,0)*8+;
IIF(INT(MOD(m.q_a,8)/4)#INT(MOD(m.q_b,8)/4),1,0)*4+;
IIF(INT(MOD(m.q_a,4)/2)#INT(MOD(m.q_b,4)/2),1,0)*2+;
IIF(INT(MOD(m.q_a,2)/1)#INT(MOD(m.q_b,2)/1),1,0)*1
*PROC ftimestamp2datetime
PARAMETER m.q_timestamp
* m.q_timestamp =
* PARAMETER: TIMESTAMP
* RETURN: Datetime
IF TYPE("m.q_timestamp")#"N"
m.q_timestamp=0
ENDI
m.q_timestamp=ABS(INT(m.q_timestamp))
PRIVATE m.q_year
m.q_year=1980+INT(m.q_timestamp/2^25) && bits 31-25
PRIVATE m.q_month
m.q_month=INT(MOD(m.q_timestamp,2^25)/2^21) && bits 24-21
PRIVATE m.q_day
m.q_day=INT(MOD(m.q_timestamp,2^21)/2^16) && bits 20-16
PRIVATE m.q_hour
m.q_hour=INT(MOD(m.q_timestamp,2^16)/2^11) && bits 15-11
PRIVATE m.q_minute
m.q_minute=INT(MOD(m.q_timestamp,2^11)/2^5) && bits 10-5
PRIVATE m.q_second
m.q_second=INT(MOD(m.q_timestamp,2^5)/2^0)*2 && bits 4-0 (two-second increments)
IF m.q_year<1
m.q_year=1
ENDI
IF m.q_year>9999
m.q_year=9999
ENDI
IF m.q_month<1
m.q_month=1
ENDI
IF m.q_month>12
m.q_month=12
ENDI
PRIVATE m.q_daymin
m.q_daymin=1
PRIVATE m.q_daymax
m.q_daymax=DAY(GOMONTH(DATE(m.q_year,m.q_month,1),+1)-1)
IF m.q_day< m.q_daymin
m.q_day=m.q_daymin
ENDI
IF m.q_day>m.q_daymax
m.q_day=m.q_daymax
ENDI
IF m.q_hour<0
m.q_hour=0
ENDI
IF m.q_hour>23
m.q_hour=23
ENDI
IF m.q_minute<0
m.q_minute=0
ENDI
IF m.q_minute>59
m.q_minute=59
ENDI
IF m.q_second<0
m.q_second=0
ENDI
IF m.q_second>59
m.q_second=59
ENDI
RETU datetime(m.q_year,m.q_month,m.q_day,m.q_hour,m.q_minute,m.q_second)
13. Other