flat assembler
Message board for the users of flat assembler.

Index > Windows > **Solved** Getting weird FASM error message

Author
Thread Post new topic Reply to topic
AlexP



Joined: 14 Nov 2007
Posts: 561
Location: Out the window. Yes, that one.
AlexP 20 Jan 2008, 01:28
I've got a kind of complex system of macro's working in my program, and I can't figure out what the fault is. It says "error, symbol already defined", and the instruction it references is .W1:mov eax,[edi-8] The .W1 is my label, and FASM (in the error dialog) has a kind of tree that brings me up about three macro layers to the actual code section, where I use .D: DecryptData This macro in turn has ScheduleWrapper macro immediately, which then has Schedule1 macro immediately. The fault .W1 label is in the Schedule1 macro, I just can't find any other place where I've used that label. I tried changing it and that hasn't worked either.


Last edited by AlexP on 20 Jan 2008, 01:54; edited 1 time in total
Post 20 Jan 2008, 01:28
View user's profile Send private message Visit poster's website Reply with quote
asmrox



Joined: 19 Jan 2008
Posts: 160
asmrox 20 Jan 2008, 01:39
post all code
Post 20 Jan 2008, 01:39
View user's profile Send private message Reply with quote
AlexP



Joined: 14 Nov 2007
Posts: 561
Location: Out the window. Yes, that one.
AlexP 20 Jan 2008, 01:46
K
Code:
format PE dll
include '%fasminc%\win32ax.inc'

;Description:
;       Template to implement:
;         256-bit symmetrical block cipher
;         Key Schedule testing routines
;         Any encryption algorithms
;
;Calling Usage:
;       TestCipher(*Key,*Data,bool Encrypt)
;
;Code Usage:
;       To add a block of key schedule code:
;         1) Create the macro appropriately named
;         2) Respect register edi = Out[i], ninth key
;         2) Add macro name to ScheduleWrapper
;       To add an encryption routine:
;         1) Re-form macro wrapper EncryptData and EncryptRound
;
;Macros:
;       PrepareSchedule
;               Prepares memory, keys
;       Schedule1
;               Rijndael key schedule implementation
;       Schedule2
;               Serpent (partial) key schedule implementation
;       Schedule3
;               Custom, Improvable algorithm
;       ScheduleRoundDiffusion
;               Per-round obfuscating sequences
;       RijndaelSubWord
;               Rijndael table substitution
;       EncryptData
;               The encryption routine
;       DecryptData
;               The decryption routine
;       EncryptRound
;               One round of the cipher
;       DecryptRound
;               One inversed round of the cipher
;       EndSchedule
;               Terminate memory, return data
;
;Sections:
;       .code
;               Main code and macros
;       .data
;               Variables used by template
;       .tdata
;               Any tables used by algorithms
;       .idata
;               Common Win32API imports
;       .edata
;               Exported functions
;
;TODO:
;  Debug PrepareSchedule
;  Debug RijnadelSchedule
;  Kind-of-Debug SerpentSchedule
;  Check overall implementation
;  Debug the encryption methods
;  Debug the decryption methods
;  Optimize the two schedules
;  Make them much smaller, check security
;  Encrypt some files or something
;    Make small thing in driver to do it for u
;  Could this be Unit Two?
;  Well, re-make the template then, and do SHA

macro EncryptData {
        ScheduleWrapper
        ;Main Encryption Loop
        lea ebx,[eax+1024]
        mov edx,[SchedulePtr]
        mov ecx,[DataPtr]
        xor esi,esi ;Data Counter
        ;Optimization Possible
    @@: ScheduleRoundDiffusion
        EncryptRound
        add edx,32 ;8 new dwords for next round
        cmp edx,ebx
        jnz @b
}

macro EncryptRound {
        ;One Round of Caesar
    @@: mov cl,byte[edx+esi] ;Schedule byte
        rol byte[ecx+esi],cl ;Data byte
        inc esi
        cmp esi,32 ;End of data?
        jnz @b
}

macro DecryptData {
        ScheduleWrapper
        ;Main Decryption Loop
        xor edx,edx
        lea ebx,[eax+1024]
        ;Optimization Possible
    @@: ScheduleRoundDiffusion
        DecryptRound
        inc edx
        cmp edx,32
        jnz @b
}

macro DecryptRound {
        ;One Round of Inv Caesar
    @@: mov cl,byte[eax+esi]
        ror byte[ecx+esi],cl
        inc esi
        cmp esi,32 ;End of data?
        jnz @b
}

macro ScheduleWrapper {
        Schedule1
        Schedule2
        Schedule3
        ScheduleRoundDiffusion
}

macro Schedule1 {
        ;Rijndael Key Schedule
        push edi
        xor edx,edx
   .W1: mov eax,[edi-8]
        mov ebx,edx
        and ebx,7
        cmp ebx,0
        jnz @f
        rol eax,8
        mov ecx,eax ;xchg?
        RijndaelSubWord
        mov eax,ecx
        shr edx,2
        xor eax,[RCon-1+edx*4] ;ERROR w/edx?
        shl edx,2
        jmp .W2
    @@: cmp ebx,4
        jnz .W2
        mov ecx,eax
        RijndaelSubWord
        mov eax,ecx
   .W2: xor eax,[edi-64]
        xor eax,[edi]
        mov [edi],eax
        add edi,4
        inc edx
        cmp edx,256 ;32 rounds * 8 dwords/round
        jnz .W1
        pop edi
}

macro Schedule2 {
        ;Partial Serpent Key Schedule
        push edi
        xor edx,edx
    .S: mov eax,[edi-64]
        xor eax,[edi-40]
        xor eax,[edi-24]
        xor eax,[edi-8]
        xor eax,[edi]
        xor eax,0x9e3779b9
        xor eax,edx
        rol eax,11
        mov [edi],eax
        add edi,4
        inc edx
        cmp edx,256 ;32 rounds * 8 dwords/round
        jnz .S
        pop edi
}

macro Schedule3 {
        ;Custom Expandable Diffusion Layer

}

macro ScheduleRoundDiffusion {
        ;Provides Schedule Diffusion Per Round
        ;Only needs to operate on eight dwords at [edx]

}

macro RijndaelSubWord {
        ;Rijndael table lookup, param in ecx
        ;Register usage optimization possible
        push eax ebx edx ecx
        movzx eax,byte[esp]
        movzx ebx,byte[esp+1]
        movzx ecx,byte[esp+2]
        movzx edx,byte[esp+3]
        mov al,byte[SBox+eax]
        mov ah,byte[SBox+ebx]
        mov bl,byte[SBox+ecx]
        mov bh,byte[SBox+edx]
        movzx ecx,bx
        shl ecx,16
        or ecx,eax
        add esp,0x4
        pop edx ebx eax
}

macro EndSchedule {
        ;Unlock the memory
        push 1024 [SchedulePtr]
        call [VirtualUnlock]
        cmp eax,0
        jnz @f
        push ErrorUnlock
        call [printf]
        add esp,4
        End
    @@: ;Free the memory
        push 0x4000 1024 [SchedulePtr]
        call [VirtualFree]
        cmp eax,0
        jnz @f
        push ErrorFree
        call [printf]
        add esp,4
        End
        @@:
}

macro End {
        ;Saves Source Space
        popa
        pop ebp
        ret 12
}

;**********************************************
;*             Template Code                 **
;**********************************************
section '.code' code readable executable
;**********************************************

PrepareSchedule:
        ;Initialization
        push ebp
        mov ebp,esp
        pusha
        ;Parameters
        mov eax,[ebp+0x8]
        mov ebx,[ebp+0xC]
        mov ecx,[ebp+0x10]
        mov [KeyPtr],eax
        mov [DataPtr],ebx
        mov [CryptChoice],ecx
        ;Allocate Memory
        push 0x04 0x3000 1024 0
        call [VirtualAlloc]
        cmp eax,0
        jnz @f
        push ErrorAlloc
        call [printf]
        add esp,4
        EndSchedule
        End
    @@: mov [SchedulePtr],eax
        ;Lock Memory
        push 1024 eax
        call [VirtualLock]
        cmp eax,0
        jnz @f
        push ErrorLock
        call [printf]
        add esp,4
        EndSchedule
        End
    @@: ;User Key -> Schedule
        mov ecx,8
        mov edi,[SchedulePtr]
        mov esi,[KeyPtr]
        rep movsd
        cmp [CryptChoice],0 ;if(Encrypt)
        jnz .D
        ;Call Encryption Routine
        EncryptData
        EndSchedule
        End
        ;Call Decryption Routine
    .D: DecryptData
        EndSchedule
        End

;**********************************************
;*          Algorithm Memory Space           **
;**********************************************
section '.data' data readable writeable
;**********************************************

;Function Data
KeyPtr DD 0      ;User key address
DataPtr DD 0     ;User data address
SchedulePtr DD 0 ;Base memory address of schedule
CryptChoice DD 0 ;Encrypt or decrypt param

;Error strings
ErrorAlloc  DB 'Could not allocate enough memory',0
ErrorFree   DB 'Could not free the memory',0
ErrorLock   DB 'Could not lock the memory',0
ErrorUnlock DB 'Could not unlock the memory',0

;**********************************************
;*           Algorithm Constants             **
;**********************************************
section '.tdata' data readable writeable
;**********************************************

SBox    db      063h,07Ch,077h,07Bh,0F2h,06Bh,06Fh,0C5h,030h,001h,067h,02Bh,0FEh,0D7h,0ABh,076h
        db      0CAh,082h,0C9h,07Dh,0FAh,059h,047h,0F0h,0ADh,0D4h,0A2h,0AFh,09Ch,0A4h,072h,0C0h
        db      0B7h,0FDh,093h,026h,036h,03Fh,0F7h,0CCh,034h,0A5h,0E5h,0F1h,071h,0D8h,031h,015h
        db      004h,0C7h,023h,0C3h,018h,096h,005h,09Ah,007h,012h,080h,0E2h,0EBh,027h,0B2h,075h
        db      009h,083h,02Ch,01Ah,01Bh,06Eh,05Ah,0A0h,052h,03Bh,0D6h,0B3h,029h,0E3h,02Fh,084h
        db      053h,0D1h,000h,0EDh,020h,0FCh,0B1h,05Bh,06Ah,0CBh,0BEh,039h,04Ah,04Ch,058h,0CFh
        db      0D0h,0EFh,0AAh,0FBh,043h,04Dh,033h,085h,045h,0F9h,002h,07Fh,050h,03Ch,09Fh,0A8h
        db      051h,0A3h,040h,08Fh,092h,09Dh,038h,0F5h,0BCh,0B6h,0DAh,021h,010h,0FFh,0F3h,0D2h
        db      0CDh,00Ch,013h,0ECh,05Fh,097h,044h,017h,0C4h,0A7h,07Eh,03Dh,064h,05Dh,019h,073h
        db      060h,081h,04Fh,0DCh,022h,02Ah,090h,088h,046h,0EEh,0B8h,014h,0DEh,05Eh,00Bh,0DBh
        db      0E0h,032h,03Ah,00Ah,049h,006h,024h,05Ch,0C2h,0D3h,0ACh,062h,091h,095h,0E4h,079h
        db      0E7h,0C8h,037h,06Dh,08Dh,0D5h,04Eh,0A9h,06Ch,056h,0F4h,0EAh,065h,07Ah,0AEh,008h
        db      0BAh,078h,025h,02Eh,01Ch,0A6h,0B4h,0C6h,0E8h,0DDh,074h,01Fh,04Bh,0BDh,08Bh,08Ah
        db      070h,03Eh,0B5h,066h,048h,003h,0F6h,00Eh,061h,035h,057h,0B9h,086h,0C1h,01Dh,09Eh
        db      0E1h,0F8h,098h,011h,069h,0D9h,08Eh,094h,09Bh,01Eh,087h,0E9h,0CEh,055h,028h,0DFh
        db      08Ch,0A1h,089h,00Dh,0BFh,0E6h,042h,068h,041h,099h,02Dh,00Fh,0B0h,054h,0BBh,016h

RCon    dd      0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a
        dd      0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39
        dd      0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a
        dd      0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8
        dd      0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef
        dd      0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc
        dd      0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b
        dd      0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3
        dd      0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94
        dd      0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20
        dd      0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35
        dd      0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f
        dd      0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04
        dd      0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63
        dd      0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd
        dd      0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb

;**********************************************
;*            Imported Functions             **
;**********************************************
section '.idata' import data readable writeable
;**********************************************

library Kernel,'Kernel32.dll',\
        Msvcrt,'Msvcrt.dll'

import Kernel,\
       VirtualAlloc,'VirtualAlloc',\
       VirtualFree,'VirtualFree',\
       VirtualLock,'VirtualLock',\
       VirtualUnlock,'VirtualUnlock'

import Msvcrt,\
       printf,'printf'

;**********************************************
;*            Exported Functions             **
;**********************************************
section '.edata' export data readable writeable
;**********************************************

export 'Cipher.dll',\
       PrepareSchedule,'TestCipher'

;**********************************************
;*             Library Relocs                **
;**********************************************
section '.reloc' fixups data discardable
;**********************************************
    

Just a little key schedule template I felt like making to test out some ideas. The schedule wrapper is just for making it simpler to inject and edit code into it, like it says in the header comments

[EDIT] Solved, apparently fasm didn't like the local label .D: for some reason. I took that off and it was fine. IDK if FASM allows local labels to point to the beginning of a macro, that was probably it.
Post 20 Jan 2008, 01:46
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jan 2008, 01:59
Schedule1 is expanded at least twice and although you used ".W1", the number of scope levels are limited to two (global and local, but no local of local of local...). So, if you replace ".D" with "D" and fix one jump you have there that refers to ".D", your code will compile. with "D" the global label "D.W1" will be defined but if you use ".D" the global label "PrepareSchedule.D" and "PrepareSchedule.W1" are defined instead and the latter will collide with the previous macro expansion (EncryptData).
Post 20 Jan 2008, 01:59
View user's profile Send private message Reply with quote
AlexP



Joined: 14 Nov 2007
Posts: 561
Location: Out the window. Yes, that one.
AlexP 20 Jan 2008, 02:25
Wow. Thanks loco, I'll remember 2 do that when I try macro's in fasm Smile Is there any way to delete a thread? Would help a lot around here...
Post 20 Jan 2008, 02:25
View user's profile Send private message Visit poster's website Reply with quote
asmrox



Joined: 19 Jan 2008
Posts: 160
asmrox 20 Jan 2008, 02:43
Quote:
Is there any way to delete a thread?

NtTerminateThread from ntdll or TerminateThread from kernel32
Post 20 Jan 2008, 02:43
View user's profile Send private message Reply with quote
AlexP



Joined: 14 Nov 2007
Posts: 561
Location: Out the window. Yes, that one.
AlexP 20 Jan 2008, 02:49
Lol I meant in the fasm forums Smile
Post 20 Jan 2008, 02:49
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jan 2008, 03:09
I see no reason for deleting it, other people could learn from it.

Note that if you don't need external access to the labels (i.e. the labels are private to the macro), you can use "local" preprocessor directive to assign an unique name each time. I suggest using labels in the form of "..name" since those doesn't affect scope of the callee. (I don't remember if using just a single dot has the same effect when you use labels previously declared with the local directive).
Post 20 Jan 2008, 03:09
View user's profile Send private message Reply with quote
AlexP



Joined: 14 Nov 2007
Posts: 561
Location: Out the window. Yes, that one.
AlexP 20 Jan 2008, 04:06
If I'm thinking right, having two dots prefixed means it's treated as a global variable? It doesn't matter much in my specific case, but I will take it in to consideration with larger projects. Thanks!
Post 20 Jan 2008, 04:06
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jan 2008, 04:23
Quote:
it's treated as a global variable?

yes, but does not affect scope

Code:
;All works
jmp a.c
jmp ..b
a:
jmp .c
..b:
.c:
jmp ..b    


Code:
jmp a.c ; it is not defined (it is b.c now)
jmp b   ; ok
a:
jmp .c  ; unreachable from current scope (you need b.c now)
b:
.c:
jmp b   ; ok    


But if you don't need any access to the local labels created by the macros then I see no difference between using one dot and using two.
Post 20 Jan 2008, 04:23
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.