I know this is not an answer "Reading stp (Designaknit Stitch Pattern)-Files)", but i think it is a way to an answer.
I believe I have the right function found (with ida - i call it testStp), but I do not know exactly what happened. I does not understand Assembler code.

I've attached the beginning of the function and the first jump point.
First, variables are declared at certain positions (var_84D ....) where and why ???
Then the stp file opens.
What makes test esi esi ??? a comparison ?? empty file ???
if ? then jnz short loc_4144FF
otherwise mov ebx, 0FFFFFFFDh || jmp loc_414C93 (exit point from the function ???)

  • fopen = open file
  • fseek = set file position
  • ftell = read current position
  • fread = read file
  • fclose = close file

mov edi, offset AD7c; "D7c" - 3 bytes read into string ???
(Which means offset ... ??)
mov ecx, 3 ???
mov esi, [esp + 34h] ????
repe CMPSB 'compare (apparently on "D7c" - the first 3 bytes in the file)
if ? then jz short loc_41458A
otherwise mov ebx, 0FFFFFFFCh | jmp loc_414C93 (exit point from the function ???)

Next I have no idea.

I hope someone can help me and tell me what the individual statements do and also mean to say whether I have the right function found. And what do sub_421CF0 do???


here are the Begin of the sub and the first jump:

.text:004144A8                 align 10h  
.text:004144B0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦  
.text:004144B0 ; int __cdecl TestSTP(int,int,int,char *,int,int)  
.text:004144B0 TestSTP         proc near               ; CODE XREF: Pattern2Sl4(x,x,x,x,x)+5A1 p  
.text:004144B0                                         ; CB_CurrentPattern(x,x,x,x)+47B p ...  
.text:004144B0 var_84D         = byte ptr -84Dh  
.text:004144B0 var_84C         = dword ptr -84Ch  
.text:004144B0 var_848         = dword ptr -848h  
.text:004144B0 var_844         = dword ptr -844h  
.text:004144B0 var_840         = dword ptr -840h  
.text:004144B0 var_83C         = word ptr -83Ch  
.text:004144B0 var_838         = dword ptr -838h  
.text:004144B0 var_834         = dword ptr -834h  
.text:004144B0 var_830         = dword ptr -830h  
.text:004144B0 var_82C         = dword ptr -82Ch  
.text:004144B0 var_828         = dword ptr -828h  
.text:004144B0 var_824         = dword ptr -824h  
.text:004144B0 var_820         = word ptr -820h  
.text:004144B0 var_81C         = dword ptr -81Ch  
.text:004144B0 var_818         = dword ptr -818h  
.text:004144B0 var_814         = dword ptr -814h  
.text:004144B0 var_810         = dword ptr -810h  
.text:004144B0 var_80C         = dword ptr -80Ch  
.text:004144B0 var_808         = dword ptr -808h  
.text:004144B0 var_804         = dword ptr -804h  
.text:004144B0 var_800         = dword ptr -800h  
.text:004144B0 var_400         = dword ptr -400h  
.text:004144B0 arg_0           = dword ptr  4  
.text:004144B0 arg_4           = dword ptr  8  
.text:004144B0 arg_8           = dword ptr  0Ch  
.text:004144B0 arg_C           = dword ptr  10h  
.text:004144B0 arg_10          = dword ptr  14h  
.text:004144B0 arg_14          = dword ptr  18h  
.text:004144B0                 sub     esp, 850h  
.text:004144B6                 mov     [esp+850h+var_818], 1  
.text:004144BE                 push    ebx  
.text:004144BF                 push    esi  
.text:004144C0                 push    edi  
.text:004144C1                 push    ebp  
.text:004144C2                 xor     edi, edi  
.text:004144C4                 mov     [esp+860h+var_82C], edi  
.text:004144C8                 mov     [esp+860h+var_80C], edi  
.text:004144CC                 cmp     [esp+860h+arg_10], edi  
.text:004144D3                 jnz     loc_41455C  
.text:004144D9                 mov     eax, [esp+860h+arg_C]  
.text:004144E0                 push    offset aRb      ; "rb"  
.text:004144E5                 push    eax             ; char *  
.text:004144E6                 call    ds:fopen  
.text:004144EC                 add     esp, 8  
.text:004144EF                 mov     esi, eax  
.text:004144F1                 test    esi, esi  
.text:004144F3                 jnz     short loc_4144FF  
.text:004144F5                 mov     ebx, 0FFFFFFFDh  
.text:004144FA                 jmp     loc_414C93  
.text:004144FF ; ------------------------------------------------  
.text:004144FF loc_4144FF:          ; CODE XREF: TestSTP+43 j  
.text:004144FF                 push    2               ; int  
.text:00414501                 mov     edi, ds:fseek  
.text:00414507                 push    0               ; __int32  
.text:00414509                 push    esi             ; FILE *  
.text:0041450A                 call    edi ; fseek  
.text:0041450C                 add     esp, 0Ch  
.text:0041450F                 push    esi             ; FILE *  
.text:00414510                 call    ds:ftell  
.text:00414516                 add     esp, 4  
.text:00414519                 mov     ebp, eax  
.text:0041451B                 push    349h  
.text:00414520                 push    offset aURefKnittingCo ; "U:\\Ref\\Knitting\\Common\\STI.C"  
.text:00414525                 push    ebp  
.text:00414526                 push    0  
.text:00414528                 call    sub_421CF0  
.text:0041452D                 mov     [esp+870h+var_82C], eax  
.text:00414531                 add     esp, 10h  
.text:00414534                 push    0               ; int  
.text:00414536                 push    0               ; __int32  
.text:00414538                 push    esi             ; FILE *  
.text:00414539                 call    edi ; fseek  
.text:0041453B                 mov     eax, [esp+86Ch+var_82C]  
.text:0041453F                 add     esp, 0Ch  
.text:00414542                 push    esi             ; FILE *  
.text:00414543                 push    1               ; size_t  
.text:00414545                 push    ebp             ; size_t  
.text:00414546                 push    eax             ; void *  
.text:00414547                 call    ds:fread  
.text:0041454D                 add     esp, 10h  
.text:00414550                 push    esi             ; FILE *  
.text:00414551                 call    ds:fclose  
.text:00414557                 add     esp, 4  
.text:0041455A                 jmp     short loc_41456E  
.text:0041455C ; ------------------------------------------------  
.text:0041455C loc_41455C:         ; CODE XREF: TestSTP+23 j  
.text:0041455C                 mov     eax, [esp+860h+arg_10]  
.text:00414563                 mov     ebp, [esp+860h+arg_14]  
.text:0041456A                 mov     [esp+860h+var_82C], eax  
.text:0041456E loc_41456E:             ; CODE XREF: TestSTP+AA j  
.text:0041456E                 mov     edi, offset aD7c ; "D7c"  
.text:00414573                 mov     ecx, 3  
.text:00414578                 mov     esi, [esp+34h]  
.text:0041457C                 repe cmpsb  
.text:0041457E                 jz      short loc_41458A  
.text:00414580                 mov     ebx, 0FFFFFFFCh  
.text:00414585                 jmp     loc_414C93  
.text:0041458A ; ------------------------------------------------  
.text:0041458A loc_41458A:             ; CODE XREF: TestSTP+CE j  
.text:0041458A                 mov     eax, [esp+860h+var_82C]  
.text:0041458E                 mov     ecx, [esp+860h+var_82C]  
.text:00414592                 mov     ax, [eax+5]  
.text:00414596                 mov     dx, [ecx+3]  
.text:0041459A         mov     word ptr [esp+860h+var_84C+2], ax  
.text:0041459F            mov     word ptr [esp+860h+var_84C], dx  
.text:004145A4                 cmp     ax, 46Ah  
.text:004145A8                 ja      loc_414C8E  
.text:004145AE                 cmp     dx, 320h  
.text:004145B3                 ja      loc_414C8E  
.text:004145B9                 mov     eax, [esp+860h+var_84C]  
.text:004145BD                 and     eax, 0FFFFh  
.text:004145C2                 mov     [esp+860h+var_840], eax  
.text:004145C6                 mov     eax, [esp+860h+var_84C+2]  
.text:004145CA                 and     eax, 0FFFFh  
.text:004145CF                 push    363h  
.text:004145D4                 mov     [esp+864h+var_814], eax  
.text:004145D8                 push    offset aURefKnittingCo ; "U:\\Ref\\Knitting\\Common\\STI.C"  
.text:004145DD                 mov     eax, [esp+868h+var_840]  
.text:004145E1                 imul    eax, [esp+868h+var_814]  
.text:004145E6                 mov     [esp+868h+var_810], eax  
.text:004145EA                 add     eax, 411h  
.text:004145EF                 mov     [esp+868h+var_824], eax  
.text:004145F3                 push    eax  
.text:004145F4                 push    0  
.text:004145F6                 call    sub_421CF0  
.text:004145FB                 mov     edx, [esp+870h+var_824]  
.text:004145FF                 mov     [esp+870h+var_830], eax  
.text:00414603                 add     esp, 10h  
.text:00414606                 mov     edi, eax  
.text:00414608                 xor     eax, eax  
.text:0041460A                 mov     ecx, edx  
.text:0041460C                 shr     ecx, 2  
.text:0041460F                 rep stosd  
.text:00414611                 mov     ecx, edx  
.text:00414613                 and     ecx, 3  
.text:00414616                 rep stosb  
.text:00414618          mov     dx, word ptr [esp+860h+var_84C+2]  
.text:0041461D                mov     ebx, dword ptr aSti ; "Sti"  
.text:00414623                 mov     eax, [esp+860h+var_830]  
.text:00414627                 mov     ecx, eax  
.text:00414629                 mov     [eax], ebx  
.text:0041462B                 mov     [eax+4], dx  
.text:0041462F                 mov     edx, [esp+860h+var_82C]  
.text:00414633            mov     ax, word ptr [esp+860h+var_84C]  
.text:00414638                 mov     [ecx+6], ax  
.text:0041463C                 mov     al, [edx+1Fh]  
.text:0041463F                 mov     ecx, [esp+860h+var_830]  
.text:00414643                 test    al, al  
.text:00414645                 jnz     short loc_414656  
.text:00414647                 mov     word ptr [ecx+8], 20h  
.text:0041464D                 add     ecx, 8  
.text:00414650                 mov     [esp+860h+var_828], ecx  
.text:00414654                 jmp     short loc_414668  
.text:00414656 ; ------------------------------------------------  
.text:00414656 loc_414656:             ; CODE XREF: TestSTP+195 j  
.text:00414656                 movsx   ax, al  
.text:0041465A                 add     ax, 100h  
.text:0041465E                 add     ecx, 8  
.text:00414661                 mov     [ecx], ax  
.text:00414664                 mov     [esp+860h+var_828], ecx  
.text:00414668 loc_414668:         ; CODE XREF: TestSTP+1A4 j  
.text:00414668                 mov     eax, [esp+860h+var_82C]  
.text:0041466C                 mov     al, [eax+2Ch]  
.text:0041466F         mov     byte ptr [esp+860h+var_820], al  
.text:00414673                 cmp     al, 0Eh  
.text:00414675                 jz      short loc_41467F  
.text:00414677                 cmp     al, 0Fh  
.text:00414679                 mov     [esp+860h+var_84D], al  
.text:0041467D                 jnz     short loc_414684  
.text:0041467F loc_41467F:          ; CODE XREF: TestSTP+1C5 j  
.text:0041467F                 mov     [esp+860h+var_84D], 0  
.text:00414684 loc_414684:          ; CODE XREF: TestSTP+1CD j  
.text:00414684                 mov     ecx, [esp+860h+var_830]  
.text:00414688            mov     al, byte ptr [esp+860h+var_820]  
.text:0041468C                 mov     dl, [esp+860h+var_84D]  
.text:00414690                 add     ecx, 410h  
.text:00414696                 mov     ebx, [esp+860h+var_830]  
.text:0041469A                 mov     esi, [esp+860h+var_82C]  
.text:0041469E                 add     ebx, 10h  
.text:004146A1                 add     esi, 0F8h  
.text:004146A7                 mov     [esp+860h+var_848], ecx  
.text:004146AB                 push    offset WindowName  
.text:004146B0                 mov     byte ptr [ecx-406h], 0  
.text:004146B7                 mov     [ecx-405h], al  
.text:004146BD                 mov     [ecx-405h], dl  
.text:004146C3                 mov     ecx, [esp+864h+var_82C]  
.text:004146C7                 push    ecx  
.text:004146C8                 call    sub_41D5A0  
.text:004146CD                 mov     eax, [esp+868h+var_84C+2]  
.text:004146D1                 mov     [esp+868h+var_808], esi  
.text:004146D5                 add     esp, 8  
.text:004146D8                 push    eax  
.text:004146D9                 push    esi  
.text:004146DA                 call    sub_4141D0  
.text:004146DF                 add     esp, 8  
.text:004146E2                 add     esi, eax  
.text:004146E4                 mov     eax, [esp+860h+var_84C+2]  
.text:004146E8                 mov     [esp+860h+var_804], esi  
.text:004146EC                 push    eax  
.text:004146ED                 push    esi  
.text:004146EE                 call    sub_4141D0  
.text:004146F3                 add     esp, 8  
.text:004146F6                 add     esi, eax  
.text:004146F8                 mov     al, [esi+6EFh]  
.text:004146FE                 mov     [esp+860h+var_834], esi  
.text:00414702                 add     esi, 6EFh  
.text:00414708                 cmp     al, 20h  
.text:0041470A                 mov     [esp+860h+var_838], esi  
.text:0041470E                 jnz     short loc_414716  
.text:00414710                 cmp     byte ptr [esi+2], 2Eh  
.text:00414714                 jz      short loc_414720  
.text:00414716 loc_414716:             ; CODE XREF: TestSTP+25E j  
.text:00414716                 cmp     byte ptr [esi+2], 20h  
.text:0041471A                 jnz     short loc_414781  
.text:0041471C                 cmp     al, 2Eh  
.text:0041471E                 jnz     short loc_414781  
.text:00414720 loc_414720:          ; CODE XREF: TestSTP+264 j  
.text:00414720                 mov     [esp+860h+var_81C], 30h  
.text:00414728                 mov     edi, esi  
.text:0041472A loc_41472A:             ; CODE XREF: TestSTP+2CF j  
.text:0041472A                 test    byte ptr [edi+1], 3  
.text:0041472E                 jz      short loc_414778  
.text:00414730                 xor     eax, eax  
.text:00414732                 mov     al, [edi]  
.text:00414734                 push    eax             ; int  
.text:00414735          push    offset a_gdejziki ; " .âäàåçêèë"  
.text:0041473A                 call    ds:__imp_strchr  
.text:00414740                 add     esp, 8  
.text:00414743                 test    eax, eax  
.text:00414745                 jz      short loc_414754  
.text:00414747      sub     eax, offset a_gdejziki ; " .âäàåçêèë"  
.text:0041474C                 mov     al, byte_42EB00[eax]  
.text:00414752                 mov     [edi], al  


.text:00421CE6                 align 10h  
.text:00421CF0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦  
.text:00421CF0 sub_421CF0      proc near ; CODE XREF: .text:00403D0C p  
.text:00421CF0                                         ; .text:00403E2C p ...  
.text:00421CF0 var_4           = dword ptr -4  
.text:00421CF0 arg_0           = dword ptr  4  
.text:00421CF0 arg_4           = dword ptr  8  
.text:00421CF0 arg_8           = dword ptr  0Ch  
.text:00421CF0 arg_C           = dword ptr  10h  
.text:00421CF0                 sub     esp, 4  
.text:00421CF3                 push    ebx  
.text:00421CF4                 push    esi  
.text:00421CF5                 mov     esi, [esp+0Ch+arg_4]  
.text:00421CF9                 push    edi  
.text:00421CFA                 push    ebp  
.text:00421CFB                 cmp     esi, 7FFFFFC0h  
.text:00421D01                 jbe     short loc_421D0D  
.text:00421D03                 xor     eax, eax  
.text:00421D05                 pop     ebp  
.text:00421D06                 pop     edi  
.text:00421D07                 pop     esi  
.text:00421D08                 pop     ebx  
.text:00421D09                 add     esp, 4  
.text:00421D0C                 retn  
.text:00421D0D ; ------------------------------------------------  
.text:00421D0D loc_421D0D:          ; CODE XREF: sub_421CF0+11 j  
.text:00421D0D                 mov     edi, [esp+14h+arg_0]  
.text:00421D11                 and     edi, 7FFFFFFFh  
.text:00421D17                 cmp     edi, 8  
.text:00421D1A                 jb      short loc_421D26  
.text:00421D1C                 xor     eax, eax  
.text:00421D1E                 pop     ebp  
.text:00421D1F                 pop     edi  
.text:00421D20                 pop     esi  
.text:00421D21                 pop     ebx  
.text:00421D22                 add     esp, 4  
.text:00421D25                 retn  
.text:00421D26 ; ------------------------------------------------  
.text:00421D26 loc_421D26:           ; CODE XREF: sub_421CF0+2A j  
.text:00421D26                 mov     eax, edi  
.text:00421D28                 shl     eax, 5  
.text:00421D2B               lea     ebx, dword_429BC8[eax+eax*2]  
.text:00421D32                 cmp     dword ptr [ebx+10h], 0  
.text:00421D36                 jnz     short loc_421D51  
.text:00421D38                 push    7Fh  
.text:00421D3A                 push    10h  
.text:00421D3C                 push    0FDh  
.text:00421D41                 push    80000h  
.text:00421D46                 push    0  
.text:00421D48                 push    ebx  
.text:00421D49                 call    sub_421ED0  
.text:00421D4E                 add     esp, 18h  
.text:00421D51 loc_421D51:           ; CODE XREF: sub_421CF0+46 j  
.text:00421D51                 cmp     [ebx+5Ch], esi  
.text:00421D54                 jnz     short loc_421D65  
.text:00421D56                 push    edi  
.text:00421D57                 push    esi  
.text:00421D58                 push    offset aSomeoneTriesTo ; "Someone tries to allocate %u bytes in p"...  
.text:00421D5D                 call    sub_420DB0  
.text:00421D62                 add     esp, 0Ch  
.text:00421D65 loc_421D65:           ; CODE XREF: sub_421CF0+64 j  
.text:00421D65                 lea     edi, [esi+2Bh]  
.text:00421D68                 mov     eax, [ebx+58h]  
.text:00421D6B                 shr     edi, 5  
.text:00421D6E                 inc     edi  
.text:00421D6F                 test    eax, eax  
.text:00421D71                 jz      short loc_421D7E  
.text:00421D73         push    0FFFFFFFFh      ; dwMilliseconds  
.text:00421D75                 push    eax             ; hHandle  
.text:00421D76                 call    ds:WaitForSingleObject  
.text:00421D7C                 jmp     short loc_421D8A  
.text:00421D7E ; ------------------------------------------------  
.text:00421D7E loc_421D7E:        ; CODE XREF: sub_421CF0+81 j  
.text:00421D7E                 lea     eax, [ebx+18h]  
.text:00421D81               mov     ebp, ds:EnterCriticalSection  
.text:00421D87        push    eax             ; lpCriticalSection  
.text:00421D88                 call    ebp ; EnterCriticalSection  
.text:00421D8A loc_421D8A:           ; CODE XREF: sub_421CF0+8C j  
.text:00421D8A                 push    edi  
.text:00421D8B                 push    esi  
.text:00421D8C                 push    ebx  
.text:00421D8D                 call    sub_421AD0  
.text:00421D92                 mov     [esp+20h+var_4], eax  
.text:00421D96                 add     esp, 0Ch  
.text:00421D99                 mov     eax, [ebx+58h]  
.text:00421D9C                 test    eax, eax  
.text:00421D9E                 jz      short loc_421DA9  
.text:00421DA0                 push    eax             ; hMutex  
.text:00421DA1                 call    ds:ReleaseMutex  
.text:00421DA7                 jmp     short loc_421DB5  
.text:00421DA9 ; ------------------------------------------------  
.text:00421DA9 loc_421DA9:           ; CODE XREF: sub_421CF0+AE j  
.text:00421DA9                 lea     eax, [ebx+18h]  
.text:00421DAC         mov     ebp, ds:LeaveCriticalSection  
.text:00421DB2        push    eax             ; lpCriticalSection  
.text:00421DB3                 call    ebp ; LeaveCriticalSection  
.text:00421DB5 loc_421DB5:           ; CODE XREF: sub_421CF0+B7 j  
.text:00421DB5                 cmp     [esp+14h+var_4], 0  
.text:00421DBA                 jz      short loc_421E18  
.text:00421DBC                 mov     edx, [esp+14h+var_4]  
.text:00421DC0                 mov     edi, [esp+14h+var_4]  
.text:00421DC4                 sub     edx, 20h  
.text:00421DC7                 xor     eax, eax  
.text:00421DC9                 mov     ecx, esi  
.text:00421DCB                 shr     ecx, 2  
.text:00421DCE                 rep stosd  
.text:00421DD0                 mov     ecx, esi  
.text:00421DD2                 and     ecx, 3  
.text:00421DD5                 rep stosb  
.text:00421DD7                 mov     ebp, [edx+4]  
.text:00421DDA                 mov     eax, [ebx+3Ch]  
.text:00421DDD                 sub     ebp, esi  
.text:00421DDF                 mov     ch, al  
.text:00421DE1                 sub     ebp, 28h  
.text:00421DE4                 mov     cl, al  
.text:00421DE6                 mov     eax, ecx  
.text:00421DE8                 mov     edi, [esp+14h+var_4]  
.text:00421DEC                 shl     eax, 10h  
.text:00421DEF                 add     edi, esi  
.text:00421DF1                 mov     ax, cx  
.text:00421DF4                 mov     ecx, ebp  
.text:00421DF6                 shr     ecx, 2  
.text:00421DF9                 rep stosd  
.text:00421DFB                 mov     ecx, ebp  
.text:00421DFD                 and     ecx, 3  
.text:00421E00                 rep stosb  
.text:00421E02                 mov     ebp, [edx+4]  
.text:00421E05                 mov     ecx, [esp+14h+arg_8]  
.text:00421E09                 mov     eax, [esp+14h+arg_C]  
.text:00421E0D                 mov     [ebp+edx-8], ecx  
.text:00421E11                 mov     ebp, [edx+4]  
.text:00421E14                 mov     [ebp+edx-4], eax  
.text:00421E18 loc_421E18:           ; CODE XREF: sub_421CF0+CA j  
.text:00421E18                 mov     eax, [esp+14h+var_4]  
.text:00421E1C                 pop     ebp  
.text:00421E1D                 pop     edi  
.text:00421E1E                 pop     esi  
.text:00421E1F                 pop     ebx  
.text:00421E20                 add     esp, 4  
.text:00421E23                 retn  
.text:00421E23 sub_421CF0      endp  


I think that Guntram Blohm has helped me (for my thanks from Germany - and I hope he help me furthermore) and we are on the right track. That's why I still try around a bit and hope to get a little more clarity. First: older Designaknit-format is *.pat. But i do not know *.sti-format??

The number of pallet data can be more than 48, perhaps, but only these 48 are important because the program has only 48 colors.
The first color (size 25 bytes) starts 325 !! (13 blocks) bytes behind the last data block. Then, the color block 48 used to follow each 25 bytes. Unused colors are marked with the number 0h. Perhaps other color blocks have been reserved (before and after the 48 palette colors) for future updates for more colors ??
The data itself is compressed by a simple run-ength-Encryption. However, the bytes have been encrypted. I made many tests and found out a lot:
Are at the beginning at the bottom left of the image a plurality of identical pixels, so you can calculate the number of this table:

left 4 bits
0 = B
16 = A
32 = 9
48 = 8
64 = F
80 = E
96 = D
112 = C

right 4 bits:
5 = 0
4 = 1
7 = 2
6 = 3
1 = 4
0 = 5
3 = 6
2 = 7
D = 8
C = 9
F = 10
9 = 12
8 = 13
B = 14
A = 15

This means if at position FC in the file z. B. B7 (hex) is so "7 = 2" pixels "B = 0" + a total of 2 same color pixel bottom left available.
This is the same for each file. However, this table thereafter at each pixel changes and is also different from file to file.
The same applies to the palette numbers. In my tests, it looked as if the pallets would thoroughly mixed after each pixel on the system. As an example, were prepared from 1 + 2 = 3 + 4, and from 3 + 4 = + 1 second This then repeated through the whole range. But it can be also mixed different (but still on the system) (Example 1 = 2, 2 = 1, 3 = 4, 4 = 3 ...) or remain the same.
ti mix, but also the change of the number of pixels is probably controlled by a key that is different from file to file changes (data for the key at positions 41h, 60h, 20h (byte), 35h (4 bytes), 39h (4 bytes) , 3dh (2 bytes) and 3fh (2 bytes) -from Guntram) I do not know if I'm right, but maybe sub_41D5A0 a simple RLE-decoding, which then decrypts the data obtained in sub_41cf20 for the key ??



Hello, your project is really very, very good and helps me a lot. I think the second part of the data block is correctly decoded. the same character (solid block of! characters) must always be displayed for jacquards. For hole pattern right / left pattern, cables etc. to change. Then, in the second section various characters appear (z. B. right Decreuse, left Decreuse, double Decreuse, eyelet, right transfer, transfer left ....) The characters are taken out of the font file to indicate this. I've just tried it and it's like I said. These files are then in the first section only same characters and in the second section of the pattern is present (with different instructions - Reassign - right - left, etc.) But the Internet almost exclusively in Jacquard stp format are available.
It would be really great I could Assembler. Thy counsel from the first mail.
Thank you very much

  • you should write it up as an Q&A item, i.e. posing the question and giving the answer yourself. This is perfectly fine on StackExchange. My highest-voted answer is of that form, too.
    – 0xC0000022L
    Mar 17, 2016 at 11:31
  • sub_41D5A0 is not a RLE decoding, the center of its loops are xor operations that are applied to the file buffer. RLE decoding happens in sub_4140F0. Mar 19, 2016 at 12:29
  • I've thrown a small program together that reads (most parts of) STP files at github.com/gbl/D7CReader. If you're going to write your program in java, feel free to copy and hack my classes; else, use them as a working example how to do the decryption. Mar 20, 2016 at 12:51

2 Answers 2


You should really learn some assembler, and x86 processor architecture, to attempt this.

To give you a bit of a start:

The var_* declarations correspond to local variables on the stack of the current function. The number of bytes between variables give you a hint about the size of these variables. For example, you have a var_400, a var_800 and a var_804. These are offsets below the top of the stack, so you have 1 variable ranging from 400 to 0 , another ranging from 800 to 400, and another from 804 to 800 (and a lot more that i omitted right now). Since these are hex numbers, and hex 400 equals dec 1024, this seems like 2 character arrays of 1K size each (likely used as buffer when reading a file), and a 4 byte integer.

A call is, like the name suggests, a function call. Before the call, function arguments are pushed on the stack; after the call, the result value is in the eax register. So, for example, before your fopen call, you see a push eax - this is the file name - and in front of that a push offset aRb - which pushes a pointer to the string "rb", which is the mode paraemter of fopen. The file name, eax, has been set in the instruction before that , mov eax, [esp+860h+arg_C], so now you know the 4th argument to this function (arg_0=1, arg_4=2, arg_8=3, arg_C=4) is the name of the file to read.

After a function call, the result is in eax. This code moves eax to esi, then tests if esi is 0 (technically, it checks if any bits are set if you and esi with itself, the test opcode does an and without storing the result. test XXX,XXX is a commonly used pattern to check if XXX is 0). If not, the function contiues; if esi is 0, "something" is done with a value of fffffffd, which corresponds to -3 . So this whole part looks like

if ((fp=fopen(filename, "rb"))==NULL)
    do_something_with(-3);               <-- probably just a return

and the esi register is used for the fp variable from then on.

Next, your code fseeks to the end of the file (see the push 2 for the whence argument, and the push 0 for the position argument), then calls ftell. Obviously it uses this to find the size of the file.

sub_421CF0 gets called with parameters (0, filesize, "U:...\STI.C", 841), and the result of sub_421CF0 is used as the buffer parameter for the following fread. Even without looking at that function, i'll bet a dollar that it uses malloc or similar to allocate memory, and throws an error message that involves the source code file name and line number in case it fails.

Later after the fread, as you said, something is compared to D7c. If you download an stp file, and hex dump it, you'll see it starts with D7c as well. So, even without checking the code further, i'd say this part returns an error (-4 corresponding to fffffffc) if the file doesn't have the correct header, and doesn't seem to be a valid stp file.

So to sum it up, yes, you seem to have found the correct function - opening a file, finding its size, allocating a buffer of that size, reading the whole file into that buffer, and checking if the buffer starts with the correct magic bytes is a clear hint at that.

(Also, you see the programmer made a cardinal error here by not checking the return value of fread; there's no guarantee fread returns as many bytes as requested even if the file size is sufficient).

But to understand the file format from that, you really have to invest a lot more time into checking what's done to the bytes that have been read. You really need to learn x86 architecture and assembler, as it's quite improbable someone will wade through all the rest of that code for you. But if you understood what i said up to here, you're on a good path.


Looking at your function a bit more closely, this seems to be a conversion function from STP files to STI files, and there is a similar function, sub_413b60, that does the same thing for files that begin with D4c and D6c, probably older file format versions.

Following the function sub_4144B0 gives good hints at the file format., extending the knowledge you found in your first question.

At offset F8, there may actually be several (1..n) blocks of data, which all have the same format:

2 bytes height
2 bytes size; this seems to be capped at 21000, read on
(size) bytes data

This height does not have to match the height that is given at file offset 5, but a height that does match that file offset denotes the end of those blocks.

After that, there's another chain of blocks of the same structure; again, the block having the height of from file offset 5 is the last block.

After that, there's 1775 bytes of Palette data, which amounts to 71 entries, not the 48 entries you had in your data format example.

The data within the abovementioned blocks is encrypted. There is a function sub_41D5A0, which uses a simple xor decryption to decrypt all of them. This function steps over blocks, decrypting them, until it finds the one having the correct height; then repeats the process.

The xor key itself is set up in sub_41cf20, which is called from the start of sub_41D5A0. This function seems to take the strings(1) from file positions 41h and 60h, and the integer values from positions 20h(byte), 35h(4 bytes), 39h (4 bytes), 3dh (2 bytes) and 3fh (2 bytes) to generate one long string, which then serves as an initializer to generate a 21000 byte xor-pattern in the static buffer at 424310. The size of this buffer, and the fact that the loop terminates at 21001, is why i said the size seems to be capped there. The key generation itself seems to be quite complicated though, so it would be neccesary to do some dynamic analysis to verify if what i assume the code does is really the case, and i haven't been able to do so, yet.

(1) String in this case means pascal-type string; 1 byte length; length bytes data.


I decoded some more of the file format, and put up a java project that can read the files at https://github.com/gbl/D7CReader.

Here's some more light on the data blocks and color palette entries:

The first chain of data blocks seems to contain the stitches themselves. After XOR decoding and RLE uncompression, it seems like mostly printable characters are used, for example '!' and digits. These characters are indexes into the color palette table; which explains why the first entries of that table - nonprintable ascii charactes - seem to be unused.

The RLE decompression is quite simple. An input byte that has its highest bit clear (<=127) is passed through as is. An input byte that has the higest bit set (>=128) is a count; the byte itself, after clearing the highest byte, is the number of repetitions, the next byte is the byte that needs to be repeated. So, for example, 83 21 means 3 repetitions of the ! character; 95 31 means 21 repetitions of 1, and 31 38 34 means 184.

When the encryption key is generated, the algorithm starts with a string of digits, then expands that string by xoring each byte with a value that is derived from the index of the byte. This means that the xor string starts with a few digits before going binary. Since all of the digits have an ascii hex value of 3X, and most of the RLE length bytes look like 8X, this explains how most of the encrypted RLE bytes start with BX, at least at the start of the encrypted RLE stream.

The second chain of data blocks seems to contain stitch types. It's RLE encoded just like the first one, but the resulting bytes are indexes into a lookup table found in the original file, behind the color table. In all my files, the result was a solid block of ! characters. There seems to be something more going on with these, and i assume this block will have some markers when the number of columns per row isn't constant, but i didn't investigate further into this.


See also https://pypi.org/project/DAKimport/ which was developed using Guntram's Java code and by further disassembly of Silverknit Utility.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.