flat assembler
Message board for the users of flat assembler.

Index > Non-x86 architectures > WinCE & ARM questions

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 15 May 2018, 13:07
revolution, can you explain this trickery:
Code:
          if $+8-_#function<4096
            ldr pc,[pc,_#function-$-8]
          else
            ldr r12,[pc]
            ldr pc,[r12]
            dw _#function
          end if    

Am I right?: pc point not to instruction start like (e|r)ip in x86, but to second one instruction after next instruction.

why second part not so:
Code:
            ldr pc,[pc]
            nop
            dw _#function    
It looks like 1 instruction shorter, but maybe I missed smthing and your variant is shortest possible?

And how you got coredll.inc it documented somewhere or you test this dll in wince, or extract it from *.BIN image?

Quote:
I drop this in first post if someone interests in emulator of arm & images for that emulator, & there are set of small programs for reverse engenering play too
https://drive.google.com/open?id=1Qe9oUFpOh_NhdM4r8i3jQoPOQXvCK4S0

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 18 May 2018, 19:15; edited 1 time in total
Post 15 May 2018, 13:07
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 15 May 2018, 13:47
ProMiNick wrote:
revolution, can you explain this trickery:
Code:
          if $+8-_#function<4096
            ldr pc,[pc,_#function-$-8]
          else
            ldr r12,[pc]
            ldr pc,[r12]
            dw _#function
          end if    

Am I right?: pc point not to instruction start like (e|r)ip in x86, but to second one instruction after next instruction.
In ARM mode the value of PC is the current instruction + 8. In Thumb mode it is a bit more complex. A single instruction can't access immediate memory offsets further than 4096 bytes away.
ProMiNick wrote:
why second part not so:
Code:
            ldr pc,[pc]
            nop
            dw _#function    
It looks like 1 instruction shorter, but maybe I missed smthing and your variant is shortest possible?
It is a pointer to a pointer. The _#function value is not a pointer to the OS function, it is an intermediate pointer to the pointer to the OS function. The OS linker/loader will only link one pointer per function, we can't coax it to make new pointers each time we call a function. Since we can't reach the offset in one instruction, we have to make it a pointer to the pointer.

Another way to code it if you have the MOVW instruction available and the address is numerically higher but less than 2^16 bytes distant is this:
Code:
movw r12,_#function-$-12
ldr pc,[pc,r12]    
ProMiNick wrote:
And how you got coredll.inc it documented somewhere or you test this dll in wince, or extract it from *.BIN image?
I have no documentation on coredll.dll. I reverse engineered the functions.

But, I wonder if there are any systems out there that still use WinCE? Maybe three people in the world use it now?
Post 15 May 2018, 13:47
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 16 May 2018, 10:12
one more...
Why apscall macros targeted for programs where programmer mix everithing within 1 PE section (sections are 4096 bytes aligned, and in many places maked macro branches that expects values distant from pc less than 4096 bytes)?
examples:
that simplification works only if we mix code & import within one section
Code:
if defined _#function & _#function-$-8<4096 & _#function-$-8>-4096
                mov lr,pc
                ldr pc,[pc,_#function-$-8]
        else
                bl function
        end if     
in common case:
Code:
bl function    


or maybe it is ARM philosophy to mix everithig(code,data) relative in 4096 range, and than next portion.

lea is not ARM instruction it is macro? it hardcoded in IDE? or it defined anywhere?
Post 16 May 2018, 10:12
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 16 May 2018, 10:34
ProMiNick wrote:
Why apscall macros targeted for programs where programmer mix everithing within 1 PE section (sections are 4096 bytes aligned, and in many places maked macro branches that expects values distant from pc less than 4096 bytes)?
The idea is that the literal pool is placed close the the code where the values are needed. It you place it too far away (more than 4096 bytes) then the instructions for accessing it become much more complex. In ARM code this is normal. The caches are designed to operate with this functionality in mind.

"function"s with a leading underscore (_) are external to the code so they need a linking call "ldr pc, ..." and the pointer is placed into the literal pool by the macros. A local function without the underscore can be called with a simple "bl ...".

The 4096 constant is not the alignment, it is the restriction in the instruction encoding for LDR.
ProMiNick wrote:
lea is not ARM instruction it is macro? it hardcoded in IDE? or it defined anywhere?
In ARM speak it is ADR. It is synthesized by the assembler, and is documented in the ARM ARM.
Post 16 May 2018, 10:34
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 16 May 2018, 13:56
how to do this:
Code:
section '.text' code readable executable
apscall RegisterClass,wc

section '.nomatter' data readable executable 
; ensure that between "apscall RegisterClass,wc" & wc definition will be more than 4096 bytes
section '.data' data readable executable
        wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class
    


there 2 variants:
use MOVEX instead of mov in PROCAPS.INC
Code:
                            if temp <> lastvalue
                                MOV lr,value
                            end if
                            lastvalue=temp
                            str lr,[sp,-tempcount*4-4]    
and in
Code:
                        else if ~ r\#p eq value
                            MOV r\#p,value
                        end if \\}     


with smthing like
Code:
macro MOVEXT dest,src {
        local ..started
        ..started:
        if src and 0ff000000h
           mov dest,src and 0ff000000h ; shifts are resolved?
       end if
       if src and 0ff0000h
          if $-..started
            orr dest,dest,src and 0ff0000h
          else
            mov dest,src and 0ff0000h
          end if
       end if
       if src and 0ff00h
          if $-..started
            orr dest,dest,src and 0ff00h
          else
            mov dest,src and 0ff00h
          end if
       end if
       if src and 0ffh
          if $-..started
            orr dest,dest,src and 0ffh
          else
            mov dest,src and 0ffh
          end if
       end if
    


or add in block
Code:
    reverse
                local ..arg
                found equ no
                match i[like]za,:parameter: \{ found equ \}
                match =no:*ustring,found:parameter \{
                    def_ustring ..arg,ustring,0
                    found equ \}
                ;add here
                match =no:some=,more,found:parameter \{
                    def_astring ..arg,parameter,0
                    found equ \}
                match =no,found \{
                  if parameter eqtype ''
                    def_astring ..arg,parameter,0
                  end if \}
                tempcount=tempcount+1     


add this
Code:
match =no:=far data,found:parameter \{
                    def_fardata ..arg,parameter
                    found equ \}    


and
Code:
macro def_fardata labl,data     {common align 4  ; is alignment needed?
labl dw data}    


so after all code (syntax) is worked
Code:
section '.text' code readable executable
apscall RegisterClass,far wc
section '.data' data readable executable
        wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class
    


previous one ever without needance in word far
Code:
                match =no,found \{
                  if parameter eqtype ''
                    def_astring ..arg,parameter,0
                  end if
                  if parameter shr 12 = $ shr 12 ; same section same page - referencing throw pc
                  else if parameter-$>200h | parameter-$<-200h ; if function located in 2 neibour pages - 512 bytes for function would be enough for referencing throw pc
                    def_fardata ..arg,parameter
                  else if
                  \}     


but
Code:
apscall CreateWindowEx,0,_class,_title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL
section '.data' data readable executable
        wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class    
still don`t

full code what I test is
Code:
format  PE GUI
entry   start

include 'WINCE.INC'

struct POINT
  x dw ?
  y dw ?
ends

struct WNDCLASS
  style         dw ?
  lpfnWndProc   dw ?
  cbClsExtra    dw ?
  cbWndExtra    dw ?
  hInstance     dw ?
  hIcon         dw ?
  hCursor       dw ?
  hbrBackground dw ?
  lpszMenuName  dw ?
  lpszClassName dw ?
ends

struct MSG
  hwnd    dw ?
  message dw ?
  wParam  dw ?
  lParam  dw ?
  time    dw ?
  pt      POINT
ends

NULL = 0
MB_ICONERROR=0    ; no matter for now
MB_OK=0           ; no matter for now
COLOR_BTNFACE=0   ; no matter for now
WM_DESTROY=$66


section '.text' code readable executable
  start:
        mov     r12,data.begin
        apscall GetModuleHandleW,0
        str     r0, [r12,wc.hInstance-data.begin]
        ;ldr     r12, [WindowProc]
        ;str     r12, [wc.lpfnWndProc]
        ;mov     r12, COLOR_BTNFACE+1
        ;str     r12, [wc.hbrBackground]
        ;ldr     r12, [_class]
        ;str     r12, [wc.lpszClassName]
        ;apscall LoadIconW,r0,IDI_APPLICATION;If I uncomment this
        ;str     r0, [r12,wc.hIcon-data.begin]; and uncomment this - next one error disapiared in compilation, but it makes exe compiled errorneusly it crashed near the call to CreateWindowExW
        apscall RegisterClassW,far wc
        cmp     r0,0
        beq     error
        apscall CreateWindowExW,0,_class,_title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL ; here I have error
        cmp     r0,0
        beq     error

  msg_loop:
        apscall GetMessageW,msg,NULL,0,0 ; {LDR R0, msg; MOV R1, NULL; MOV R2, #0; MOV R3, #0; BL GetMessage}
        cmp     r0, 0
        beq     end_loop
        apscall TranslateMessage,msg ; {LDR R0, msg; BL TranslateMessage}
        apscall DispatchMessageW,msg ; {LDR R0, msg; BL DispatchMessage}
        b       msg_loop

  error: 
        apscall MessageBoxW,NULL,_error,NULL,MB_ICONERROR+MB_OK ; MOV R0, NULL; LDR R1, _error; MOV R2, NULL; MOV R3, MB_ICONERROR+MB_OK; BL MessageBox}

  end_loop: 
        apscall ExitThread,0

proc WindowProc nospil ,hwnd,wmsg,wparam,lparam
        cmp     r1,WM_DESTROY
        beq     .wmdestroy
  .defwndproc:
        apscall DefWindowProcW,R0,R1,R2,R3
        B       .finish
  .wmdestroy:
        apscall PostQuitMessage,0
        mov     r0,0
  .finish:
        ret
endp

section '.data' data readable executable
        data.begin:
        _class du 'FASMWINCE',0
        _title du 'WinCE program template',0
        _error du 'Startup failed.',0

        wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class
        msg MSG

section '.idata' import data readable writeable

        library coredll,'COREDLL.DLL'
        include 'APICE\COREDLL.INC'    
Post 16 May 2018, 13:56
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 16 May 2018, 14:08
IF you need the address of WindowProc then try with ADR, instead of LDR.

Also, you can't address wc directly. You will need to load the address into a register first (maybe with ADR also), then you can use "str r12,[r0,WNDCLASS.lpfnWndProc]", assuming r0 is the address of wc.
Post 16 May 2018, 14:08
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 16 May 2018, 14:48
patched PROCAPS.INC:
Code:
macro def_ustring labl,[string] {common labl dU string}
macro def_astring labl,[string] {common labl dB string}     
added
Code:
macro def_fardata labl,data     {common align 4  ; is alignment needed?
labl dw data}     
Code:
macro apscall function,[parameter] {
    common
        local pcount,tempcount,found,.skip,.size,param,last_value,temp,size,instr,i_s,msize
        virtual
                nop
                temp=$-$$
        end virtual
        if temp<>4
                halt ;APSCALL macro NOT usable in thumb mode
        end if
        if ~ parameter eq
                if .size
                    b .skip
                end if
                temp=$
                tempcount=0
    reverse
                local ..arg
                found equ no
                match i[like]za,:parameter: \{    
added
Code:
                  if  like eqtype 0
                    if like shr 12 = $ shr 12 ; same section same page
                    else if like-$>200h | like-$<-200h
                      def_fardata ..arg,like
                    end if
                  end if    
Code:
                found equ \}
                match =no:*ustring,found:parameter \{
                    def_ustring ..arg,ustring,0
                    found equ \}
                match =no:some=,more,found:parameter \{
                    def_astring ..arg,parameter,0
                    found equ \}
                match =no,found \{
                  if parameter eqtype ''
                    def_astring ..arg,parameter,0
                  end if    
added
Code:
                  if  parameter eqtype 0
                    if parameter shr 12 = $ shr 12 ; same section same page
                    else if parameter-$>200h | parameter-$<-200h
                      def_fardata ..arg,parameter
                    end if
                  end if    
Code:
                  \}
                tempcount=tempcount+1
    common
                pcount=tempcount
                align 4
                .size=$-temp
                if .size
                    .skip:
                end if
                lastvalue=1 shl 63
                tempcount=0
    reverse
                if tempcount<(pcount-4)
                    found equ no
                    define param parameter
                    match [address],parameter \{    
added
Code:
                        if defined ..arg
                          ADD lr,pc,..arg-$-8
                          LDR lr,[lr]
                        else     
Code:
                          LDR lr,[address]    
added
Code:
                        end if    

all rest remain untouched

compiled successfuly, but


Description:
Filesize: 184.05 KB
Viewed: 30095 Time(s)

wince.jpg



_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 16 May 2018, 14:48
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 17 May 2018, 23:48
I canceled from avoiding word far in PROCAPS.
word far precedes values that used from other PE sections and therefore needed in special handling.

Code:
format  PE GUI
entry   start

include 'WINCE.INC'

struct POINT
  x dw ?
  y dw ?
ends

struct WNDCLASS
  style         dw ?
  lpfnWndProc   dw ?
  cbClsExtra    dw ?
  cbWndExtra    dw ?
  hInstance     dw ?
  hIcon         dw ?
  hCursor       dw ?
  hbrBackground dw ?
  lpszMenuName  dw ?
  lpszClassName dw ?
ends

struct MSG
  hwnd    dw ?
  message dw ?
  wParam  dw ?
  lParam  dw ?
  time    dw ?
  pt      POINT
ends

NULL = 0
MB_ICONERROR=0    ; no matter for now
MB_OK=0           ; no matter for now
COLOR_BTNFACE=0   ; no matter for now
WM_DESTROY=$66

section '.text' code readable executable
  start:
        mov     r12,data.begin
        apscall GetModuleHandleW,0
        str     r0, [r12,wc.hInstance-data.begin]
        apscall RegisterClassW,far wc
        cmp     r0,0
        beq     error ; on call CreateWindowExW emulated WinCE OS freezes, if change beq with b then showed message "Startup failed." and program normaly closed
        apscall CreateWindowExW,0,far _class,far _title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL ; here I have error
        cmp     r0,0
        beq     error

  msg_loop:
        apscall GetMessageW,far msg,NULL,0,0 ; {LDR R0, msg; MOV R1, NULL; MOV R2, #0; MOV R3, #0; BL GetMessage}
        cmp     r0, 0
        beq     end_loop
        apscall TranslateMessage,far msg ; {LDR R0, msg; BL TranslateMessage}
        apscall DispatchMessageW,far msg ; {LDR R0, msg; BL DispatchMessage}
        b       msg_loop

  error: 
        apscall MessageBoxW,NULL,far _error,NULL,MB_ICONERROR+MB_OK ; MOV R0, NULL; LDR R1, _error; MOV R2, NULL; MOV R3, MB_ICONERROR+MB_OK; BL MessageBox}

  end_loop: 
        apscall ExitThread,0

proc WindowProc nospil ,hwnd,wmsg,wparam,lparam
        cmp     r1,WM_DESTROY
        beq     .wmdestroy
  .defwndproc:
        apscall DefWindowProcW,R0,R1,R2,R3
        B       .finish
  .wmdestroy:
        apscall PostQuitMessage,0
        mov     r0,0
  .finish:
        ret
endp

section '.skip' data readable writeable 
        dd 0

section '.data' data readable writeable ; accidentaly previously section has executable flag instead of writeable
        data.begin:
        _class du 'FASMWINCE',0
        _title du 'WinCE program template',0
        _error du 'Startup failed.',0
        align 4 ; when wc was misaligned program was crashed in "str     r0, [r12,wc.hInstance-data.begin]"
        wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class
        msg MSG

section '.idata' import data readable writeable

        library coredll,'COREDLL.DLL'
        include 'APICE\COREDLL.INC'    


Any ideas what is wrong in CreateWindowExW or in WindowProc processing?


Description:
Download
Filename: PROCAPS.INC
Filesize: 20.44 KB
Downloaded: 946 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 17 May 2018, 23:48
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 18 May 2018, 06:56
Can you attach a full set of sources for the code you assembled?. I'll see what I can find.
Post 18 May 2018, 06:56
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 18 May 2018, 10:17
program donor for ideas attached
7kb in size (in wince HLL wrapper around main is perfect - it has many lines of code that actualy does nothing!)


Description: I already cleared in it all hll shit around of start - so it is still normal work. & listing inside
Download
Filename: Utilities.zip
Filesize: 30.35 KB
Downloaded: 929 Time(s)

Description: my fasmarm with corrections in procaps
Download
Filename: FASMARM.zip
Filesize: 736.26 KB
Downloaded: 922 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 18 May 2018, 10:17
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 23 May 2018, 10:39
I patched winmain(start) in donor file so it will have more suitable form for making macros over it
Code:
start                                   ; DATA XREF: HEADER:00010100o                                                                                                                                                
                                        ; HEADER:00010104o ...                                                                                                                                                       
                                                                                                                                                                                                                      
X               = -0x78                                                                                                                                                                                               
Y               = -0x74                                                                                                                                                                                               
nWidth          = -0x70                                                                                                                                                                                               
nHeight         = -0x6C                                                                                                                                                                                               
hWndParent      = -0x68                                                                                                                                                                                               
hMenu           = -0x64                                                                                                                                                                                               
hInstance       = -0x60                                                                                                                                                                                               
lpParam         = -0x5C                                                                                                                                                                                               
Msg             = -0x50                                                                                                                                                                                               
WndClass        = -0x30                                                                                                                                                                                               
                                                                                                                                                                                                                      
                STMFD           SP!, {R0,LR}                                                                                                                                                                          
                SUB             SP, SP, #0x70                                                                                                                                                                         
                STR             R0, [SP,#0x78+WndClass.hInstance]                                                                                                                                                     
                LDR             R6, =dword_131F0                                                                                                                                                                 
                STR             R0, [R6]                                                                                                                                                                              
                MOV             R5, R0                                                                                                                                                                                
                ANDEQ           R0, R0, R0 ;smthing as nop only placeholder code is shrinked after optimizing
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                ANDEQ           R0, R0, R0 ;smthing as nop
                MOV             R0, #0  ; int                                                                                                                                                                         
                STR             R0, [SP,#0x78+WndClass.cbClsExtra]                                                                                                                                                    
                STR             R0, [SP,#0x78+WndClass.cbWndExtra]                                                                                                                                                    
                STR             R0, [SP,#0x78+WndClass.hCursor]                                                                                                                                                       
                STR             R0, [SP,#0x78+WndClass.lpszMenuName]                                                                                                                                                  
                BL              GetStockObject                                                                                                                                                                        
                STR             R0, [SP,#0x78+WndClass.hbrBackground]                                                                                                                                                 
                LDR             R1, =aIdi_icon1 ; "IDI_ICON1"                                                                                                                                                         
                MOV             R0, #0  ; hInstance                                                                                                                                                                   
                BL              LoadIconW                                                                                                                                                                             
                STR             R0, [SP,#0x78+WndClass.hIcon]                                                                                                                                                         
                MOV             R0, #1                                                                                                                                                                                
                STR             R0, [SP,#0x78+WndClass]                                                                                                                                                               
                LDR             R0, =sub_111A0                                                                                                                                                                        
                STR             R0, [SP,#0x78+WndClass.lpfnWndProc]                                                                                                                                                   
                LDR             R7, =aYusu ; "Yusu"                                                                                                                                                                   
                STR             R7, [SP,#0x78+WndClass.lpszClassName]                                                                                                                                                 
                ADD             R0, SP, #0x78+WndClass ; lpWndClass                                                                                                                                                   
                BL              RegisterClassW                                                                                                                                                                        
                MOV             R1, R0,LSL#16                                                                                                                                                                         
                MOVS            R0, R1,LSR#16                                                                                                                                                                         
                ADDEQ           SP, SP, #0x70                                                                                                                                                                         
                LDMEQFD         SP!, {R0,PC}                                                                                                                                                                          
                MOV             R0, #0  ; nIndex                                                                                                                                                                      
                BL              GetSystemMetrics                                                                                                                                                                      
                LDR             R1, =dword_131E0                                                                                                                                                                      
                STR             R0, [R1]                                                                                                                                                                              
                STR             R0, [SP,#0x78+nWidth] ; nWidth  ;maybe for macro value should be saved in r6 that free for use here
                MOV             R0, #1  ; nIndex                                                                                                                                                                      
                BL              GetSystemMetrics                                                                                                                                                                      
                LDR             R1, =dword_131E4                                                                                                                                                                      
                STR             R0, [R1]                                                                                                                                                                              
                STR             R0, [SP,#0x78+nHeight] ; nHeight ;maybe for macro value should be saved in r8 that free for use here
                MOV             R0, #0  ; dwExStyle  ; this line would precede apscall macro
                STR             R0, [SP,#0x78+lpParam] ; lpParam                                                                                                                                                      
                STR             R5, [SP,#0x78+hInstance] ; hInstance                                                                                                                                                  
                STR             R0, [SP,#0x78+hMenu] ; hMenu                                                                                                                                                          
                STR             R0, [SP,#0x78+hWndParent] ; hWndParent                                                                                                                                                
                STR             R0, [SP,#0x78+Y] ; Y                                                                                                                                                                  
                STR             R0, [SP,#0x78+X] ; X                                                                                                                                                                  
                MOV             R3, #0x10000000 ; dwStyle                                                                                                                                                             
                LDR             R2, =aSysneitfSearch ; "Sysneitf Search"                                                                                                                                              
                MOV             R1, R7  ; lpClassName                                                                                                                                                                 
                BL              CreateWindowExW ;r0,r7,far aSysneitfSearch,$10000000,r0,r0,r6,r8,r0,r0,r5,r0
                MOVS            R4, R0                                                                                                                                                                                
                MOVEQ           R0, #0                                                                                                                                                                                
                ADDEQ           SP, SP, #0x70                                                                                                                                                                         
                LDMEQFD         SP!, {R0,PC}                                                                                                                                                                          
                LDR             R1, =aAccelerator1 ; "Accelerator1"                                                                                                                                                   
                MOV             R0, R5  ; hInstance                                                                                                                                                                   
                BL              LoadAcceleratorsW                                                                                                                                                                     
                MOV             R8, R0                                                                                                                                                                                
                MOV             R1, R9  ; nCmdShow                                                                                                                                                                    
                MOV             R0, R4  ; hwnd                                                                                                                                                                        
                BL              ShowWindow                                                                                                                                                                            
                MOV             R0, R4  ; hwnd                                                                                                                                                                        
                BL              UpdateWindow                                                                                                                                                                          
                                                                                                                                                                                                                      
loc_1112C                               ; CODE XREF: start+15Cj                                                                                                                                                      
                                        ; start+170j                                                                                                                                                                 
                MOV             R3, #0  ; wMsgFilterMax                                                                                                                                                               
                MOV             R2, #0  ; wMsgFilterMin                                                                                                                                                               
                MOV             R1, #0  ; hWnd                                                                                                                                                                        
                ADD             R0, SP, #0x78+Msg ; lpMsg                                                                                                                                                             
                BL              GetMessageW                                                                                                                                                                           
                CMP             R0, #0                                                                                                                                                                                
                BEQ             loc_11174                                                                                                                                                                             
                ADD             R2, SP, #0x78+Msg ; lpMsg                                                                                                                                                             
                MOV             R1, R8  ; hAccTable                                                                                                                                                                   
                MOV             R0, R4  ; hWnd                                                                                                                                                                        
                BL              TranslateAcceleratorW                                                                                                                                                                 
                CMP             R0, #0                                                                                                                                                                                
                BNE             loc_1112C                                                                                                                                                                             
                ADD             R0, SP, #0x78+Msg ; pMsg                                                                                                                                                              
                BL              TranslateMessage                                                                                                                                                                      
                ADD             R0, SP, #0x78+Msg ; lpMsg                                                                                                                                                             
                BL              DispatchMessageW                                                                                                                                                                      
                B               loc_1112C                                                                                                                                                                             
; ---------------------------------------------------------------------------                                                                                                                                         
                                                                                                                                                                                                                      
loc_11174                               ; CODE XREF: start+144j                                                                                                                                                      
                LDR             R0, [SP,#0x78+Msg.wParam]                                                                                                                                                             
                ADD             SP, SP, #0x70                                                                                                                                                                         
                LDMFD           SP!, {R0,PC}                                                                                                                                                                          
; End of function start     

of course after patch exe still works normally

once again trying to make app (not task) in WinCE:
Code:
        format  PE GUI
        entry   start
        include 'WINCE.INC'

struct POINT
  x dw ?
  y dw ?
ends

struct WNDCLASS
  style         dw ?
  lpfnWndProc   dw ?
  cbClsExtra    dw ?
  cbWndExtra    dw ?
  hInstance     dw ?
  hIcon         dw ?
  hCursor       dw ?
  hbrBackground dw ?
  lpszMenuName  dw ?
  lpszClassName dw ?
ends

struct MSG
  hwnd    dw ?
  message dw ?
  wParam  dw ?
  lParam  dw ?
  time    dw ?
  pt      POINT
ends

section '.text' code readable executable

start:
virtual at sp
  x          dw ?
  y          dw ?
  nWidth     dw ?
  nHeight    dw ?
  hWndParent dw ?
  hMenu      dw ?
  hInstance  dw ?
  lpParam    dw ?
  Msg        MSG
  WndClass   WNDCLASS
end virtual
        stmfd   sp!, {r0,lr}
        sub     sp, sp, $70
        str     r0, [WndClass.hInstance]
        ;ldr     r6, [pc+..off_11198-$-8] ;ldr     r6, =dword_131F0
        ;str     r0, [r6]
        mov     r5, r0
        mov     r0, 0
        str     r0, [WndClass.cbClsExtra]
        str     r0, [WndClass.cbWndExtra]
        str     r0, [WndClass.hCursor]
        str     r0, [WndClass.lpszMenuName]
        ;apscall LoadIconW,0,[..off_1119C]
        str     r0, [WndClass.hIcon]
        apscall GetStockObject,r0
        str     r0, [WndClass.hbrBackground]
        mov     r0, #1
        str     r0, [WndClass]
        ldr     r0, [pc+..off_11194-$-8] ;ldr     r0, =sub_111A0
        str     r0, [WndClass.lpfnWndProc]
        ldr     r7, [pc+..off_11190-$-8] ;ldr     r7, =_class
        str     r7, [WndClass.lpszClassName]
        apscall RegisterClassW, addr WndClass
        mov     r1, r0,lsl 16
        movs    r0, r1,LSR 16
        addeq   sp, sp, $70
        ldmeqfd sp!, {r0,pc}
        apscall GetSystemMetrics,0
        ;ldr     r1, [pc+..off_11188-$-8] ;ldr     r1, =dword_131E0
        ;str     r0, [r1]
        mov     r6, r0 ;str     r0, [nWidth]
        apscall GetSystemMetrics,1
        ;ldr     r1, [pc+..off_11184-$-8] ;ldr     r1, =dword_131E0
        ;str     r0, [r1]
        mov     r8, r0 ;str     r0, [nWidth]
        mov     r0, 0
        apscall CreateWindowExW,r0,r7,[..off_11180],$10000000,r0,r0,r6,r8,r0,r0,r5,r0
        movs    r4, r0
        addeq   sp, sp, $70
        ldmeqfd sp!, {r0,pc}
        ;apscall LoadAcceleratorsW,r5,[..off_1118C]
        ;mov     r8, r0
        apscall MessageBoxW,0,addr Text,addr Caption,0+0
        apscall ExitThread,0
        mov     r8, r0
        apscall ShowWindow,r4,r9
        apscall UpdateWindow,r4

  msg_loop:

        apscall GetMessageW,addr Msg,0,0,0
        cmp     r0, 0
        beq     end_loop
        ;apscall TranslateAcceleratorW,r4,r8,0,0
        ;cmp     r0, 0
        ;bne     msg_loop
        apscall TranslateMessage,addr Msg
        apscall DispatchMessageW,addr Msg
        b       msg_loop
  end_loop:
        ldr     r0, [Msg.wParam]
        add     sp, sp, $70
        ldmfd sp!, {r0,pc}

..off_11180 dw    _title
;..off_11184 dw    dword_131E4
;..off_11188 dw    dword_131E0
..off_1118C dw    aAccelerator1
..off_11190 dw    _class
..off_11194 dw    WndProc ;WndProc
;..off_11198 dw    dword_131F0
..off_1119C dw    aIdi_icon1

WndProc:
        stmfd   sp!, {r4-r8,r11,lr}
        mov     r5,r0
        mov     r7,r2
        mov     r8,r3
        cmp     r1,2
        beq     .wmdestroy
        apscall DefWindowProcW,r0,r1,r2,r3
        ldmfd   sp!, {r4-r8,r11,PC}
  .wmdestroy:
        apscall PostQuitMessage,0
        mov     r0,0
        ldmfd   sp!, {r4-r8,r11,PC}

section '.data' data readable writeable
  _class du 'Yusu',0
  _title du 'WinCE example app',0
  ;aIdi_icon1 du 'IDI_ICON1',0
  ;aAccelerator1 du 'Accelerator1',0
  ;dword_131E0 dw ?
  ;dword_131E4 dw ?
  ;dword_131F0 dw ?

section '.idata' import readable writeable

        library coredll,'COREDLL.DLL'
        include 'APICE\COREDLL.INC'      
problem apscall dos`n operate with locals defined via virtual not throw local. How make proc wrapper that makes exatctly that "STMFD SP!, {R0,LR};SUB SP, SP, #0x70"?


Description:
Download
Filename: search3.zip
Filesize: 2.38 KB
Downloaded: 905 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 23 May 2018, 10:39
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2018, 11:03
Just a first look at your code I see this problem:
Code:
        mov     r12,data.begin
        apscall GetModuleHandleW,0
        str     r0, [r12,wc.hInstance-data.begin]    
R12 is not preserved in the ARM procedure call standard. So expect it to be corrupted by the call.
Post 24 May 2018, 11:03
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 24 May 2018, 15:05
revolution wrote:
Just a first look at your code I see this problem:
Code:
        mov     r12,data.begin
        apscall GetModuleHandleW,0
        str     r0, [r12,wc.hInstance-data.begin]    
R12 is not preserved in the ARM procedure call standard. So expect it to be corrupted by the call.

Code:
        apscall GetModuleHandleW,0
        mov     r12,data.begin
        str     r0, [r12,wc.hInstance-data.begin]    


I fix it in my sources (sometime before your post), but fasmarm compilled application with window message processing still not workable.

And some more qustions:
If we expect that entry point is procedure where pc finaly restored from lr, we must preserve ProcessID stored in r0 (and even more we can preserve r1 with unknown meaningless value instead of preserving r0 and it is worked too) or we can trash every register end close app with ExitThread. Any idea what in r1?

what for macro locals is? "locals" can`t serve all cases for which it made. Yes, values itself from locals are valid to pass as params to apscall, but ptr to that values are not.

spill - is stack shadow of registers?

I think more and more that mov should be overloaded by macro.
We can mov to register good value (value where 24 freely shifted neibour bits are all set or all unset),we can mov to register sp or pc relative value that in range 4096 around of pc & sp, mov should handle cases when value is no good.

placing pc relative values infront of each apscall I think it breaks all arm philosophy targeted to make code less branched. other compilers place this values at spaces where is no needance in skipping that data (after b branch or after restoring pc)

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 24 May 2018, 15:05
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2018, 15:39
I think the macros should only be used for convenience when we can afford to be lazy. If you are concerned about a philosophical approach then I don't think the macros are a good solution. The macros become very complex when you consider all the variants of the CPU core instruction sets. I added an undocumented "fit" operator for when I was testing with macros to do all the complex loading and storing of all the various ways values can be used. The program then takes a very long time to assemble code of any useful length. Macros are good for small tests and short code that doesn't go into production IMO. For more realistic code not so much.

There are many ways approach the problem of loading values and constants. Macros will often constrain you to only one way, and there might be a much better way for some particular piece of code. So you might frequently find yourself manually writing sections of code to accommodate the special situation. There is nothing wrong with doing that IMO. When you need it, then you need it, so do it. But it also makes the macros kind of useless and limiting. Plus they hide a lot of what is happening underneath. In my testing I found that if one extends the macros to cover lots and lots of special cases the assembly time becomes prohibitive. Whereas a human could see the solution immediately when writing the code.

In constrained environments like many ARM systems it is often necessary to take more control over the precise instructions being used. This is where macros will hurt you also.

WinCE is not very popular these days. Do MS still update it?
Post 24 May 2018, 15:39
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2018, 15:56
I notice in your macro that the parameter "[wc.hInstance]" is coded as:
Code:
00000430: 00013074 V1     dw 0x00013074
;...
00000444: E24FE01C V1     sub   r14,r15,=0x430
00000448: E59EE000 V1     ldr   r14,[r14]
0000044C: E50DE008 V1     str   r14,[r13,-0x8]    
So it doesn't load the value from [wc.hInstance], it loads the address of wc.hInstance. You will need to load the address first and then load the value, a pointer to a pointer.
Post 24 May 2018, 15:56
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 24 May 2018, 19:47
Maybe I`ll chosed smthing more modern, but when I read how to program for android I completely dissapointed in it (I waiting when dalvik technology will die). How to test WinPhone or IPhone app without device - no way. ARM LLinux is it exists? where it can be tested in qemu?
After all of that I stoped on WinCE for meeting with arm.

WinCE minuses:
I never hear about it in days when it was exist.
I don`t know is any device in nowadays that runned such OS.

WinCE pluses:
I can reuse windows includes for not x86.
I can emulate it.
I can touch arm.
Because OS targeted for ARM 4i,ARM 5i macros for it can be not so complex - instruction variance is present in coprocessor mostly (I not targeted for fpu, I already played with x86 fpu instructions, and for now trying to avoid using of them everywhere exept places where they exactly needed).

P.S. Macros not only for lazy programmers, but for programmers that prefer to share its code - with macros it can be more readeble.
Post 24 May 2018, 19:47
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 25 May 2018, 03:55
ProMiNick wrote:
P.S. Macros not only for lazy programmers, but for programmers that prefer to share its code - with macros it can be more readeble.
Perhaps you are correct that it will be more readable, but I think it is also less understandable about what the CPU is asked to do. The macros make it more like HLL and obscure the link to the underlying instructions. Usually an HLL will make sure everything works as intended, but for assembly coders things are not so well controlled.

A good example of the lessened understanding is the invoke macro for x86. If you use the addr operator then the register edx is corrupted. There is no indication that edx is being used when looking at the source code. The following code is seriously buggy
Code:
mov edx,[some_pointer]
invoke SomeFunction, dword[edx+4], addr esi+8    
... but this code is perfectly fine
Code:
mov edx,[some_pointer]
invoke SomeFunction, addr esi+8, dword[edx+4]    
This was part of my previous experiment where I tried to detect all the various problems and find ways around them. If someone used R12 as a source operand then I could use R14 as a temporary, and if someone used R14 as a source operand then I could use R12. But what happens when both R12 and R14 are used as sources? There are ways to do it that involve the stack but the code quickly gets ugly, and the assembly time balloons out of control with the macros trying to detect all this kind of stuff and changing the code to accommodate it.

A major problem is the loading of constants. We can create literal pools and place them in convenient locations near the function code so we don't need to branch over each constant. But that requires keeping a store of them within the assembler memory and later depositing them at the end of the function. But what happens if the function is more than 4096 bytes and the code can't reach the constants? So then we start finding ways to deposit the pool after each unconditional branch (and there are lots of ways to make an unconditional branch). But we also want to keep the constants aligned and together with the each other so as not to waste the limited dcache lines with useless instruction bytes intermixed, while at the same time not wasting the limited icache lines with useless padding bytes. Add to that the possibility of sharing constants between functions. Maybe a preceding function uses a constant we need. Then we can search the previous literal pools to try and find our constant and load that instead of storing a new one. But the search is time consuming and not guaranteed to find what we need. All of these have solutions, but finding them with macros is not much fun.
Post 25 May 2018, 03:55
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 04 Jun 2018, 10:11
[post edited]
Atlast I make it (WinCE app with message processing) work and work correctly.
First of all macros in importce.inc targeted to single imported library.
I have to use 2 libraries so importce.inc patched:
Code:
;FASMARM extension macros:
;
;Macros for imports section in PE file generation
;
;LIBRARY:
;
;  Usage: library name1,string1,name2,string2,...
;
;  name   - a prefix for program labels identifying data structures
;  string - a text ascii string identifying the DLL filename
;
;
;IMPORT:
;
;  Usage: import name,function1,string1,function2,string2,...
;
;  name     - a prefix for program labels identifying data structures
;  label    - program label for the import
;  string   - the DLL exported ordinal (no matter with sign bit or not) or literal
;
;By default this file is included from "WINCE.INC".


macro library [name,string]
 { common
    import.data:
   forward
    local _label
    if defined name#.redundant
     if ~ name#.redundant
      dw RVA name#.lookup,0,0,RVA _label,RVA name#.address
     end if
    end if
    name#.referred = 1
   common
    rw 5
   forward
    if defined name#.redundant
     if ~ name#.redundant
      _label db string,0
             rb RVA $ and 1
     end if
    end if }

macro import name,[label,string]
 { common
    rb (- rva $) and 3
    if defined name#.referred
     name#.lookup:
   forward
     if used label
      if string eqtype ''
       local _label
       dw RVA _label
      else
       dw 80000000h or string
      end if
     end if
   common
     if $ > name#.lookup
      name#.redundant = 0
      dw 0
     else
      name#.redundant = 1
     end if
     name#.address:
   forward
     if used label
      name#.#label dw ?
     end if
   common
     if ~ name#.redundant
      dw 0
     end if
   forward
     if used label
      label:
       if $+8-name#.#label<$0FFF
        ldr pc,[pc,name#.#label-$-8]
       else
        ldr r12,[pc]
        ldr pc,[r12]
        dw name#.#label
       end if
     end if
   forward
     if used label & string eqtype ''
     _label dh 0
            db string,0
            rb RVA $ and 1
     end if
   common
    end if }     


and declaration of 2nd library (its imports that I know):
COMMCTRL.INC:
Code:
import commctrl,\
        CommandBar_Create,'CommandBar_Create',\
        CommandBar_AddAdornments,'CommandBar_AddAdornments',\
        CommandBar_InsertMenubarEx,'CommandBar_InsertMenubarEx',\
        CommandBar_Height,'CommandBar_Height'    


and source file itself (WINCE.ASM):
Code:
        format  PE GUI
        entry   Start

        include 'WINCE.INC'

struct POINT
  x dw ?
  y dw ?
ends

struct WNDCLASS
  style         dw ?
  lpfnWndProc   dw ?
  cbClsExtra    dw ?
  cbWndExtra    dw ?
  hInstance     dw ?
  hIcon         dw ?
  hCursor       dw ?
  hbrBackground dw ?
  lpszMenuName  dw ?
  lpszClassName dw ?
ends

struct MSG
  hwnd    dw ?
  message dw ?
  wParam  dw ?
  lParam  dw ?
  time    dw ?
  pt      POINT
ends

section '.text' code readable executable

Start:
        stmfd   sp!,{r0,lr}
        sub     sp,sp,$20
        mov     r5,r0
        ldr     r6,[pc+.local.lpwc-$-8]
        str     r5,[r6+WNDCLASS.hInstance]
        apscall RegisterClassW,r6
        mov     r1, r0,lsl#16
        movs    r0, r1,lsr#16
        addeq   sp,sp,$20
        ldmeqfd sp!,{r0,pc}
        apscall GetSystemMetrics,0
        ldr     r1,[pc+.local.lpwidth-$-8]
        str     r0,[r1]
        mov     r4,r0
        apscall GetSystemMetrics,1
        ldr     r1,[pc+.local.lpheight-$-8]
        str     r0,[r1]
        mov     r7,r0
        mov     r0,0
        str     r0,[sp+$1C]
        str     r5,[sp+$18]
        str     r0,[sp+$14]
        str     r0,[sp+$10]
        str     r7,[sp+$0C]
        str     r4,[sp+$08]
        str     r0,[sp+$04]
        str     r0,[sp+$00]
        mov     a4,$10000000
        ldr     a3,[pc+.local.lptitle-$-8]
        ldr     a2,[r6+WNDCLASS.lpszClassName]
        ;mov    a1,r0
        bl      CreateWindowExW
        movs    r4,r0
        addeq   sp,sp,$20
        ldmeqfd sp!,{r0,pc}
        apscall ShowWindow,r0,r9
        apscall UpdateWindow,r4
  .msg_loop:
        mov     r3,0
        mov     r2,0
        mov     r1,0
        add     r0,pc,.msg_loop.msg-$-8
        bl      GetMessageW
        cmp     r0,0
        beq     .end_loop
        add     r0,pc,.msg_loop.msg-$-8
        bl      TranslateMessage
        add     r0,pc,.msg_loop.msg-$-8
        bl      DispatchMessageW
        b       .msg_loop

  .msg_loop.msg MSG

  .end_loop:
        ldr     r0,[pc+.msg_loop.msg.wParam-$-8]
        add     sp,sp,$20
        ldmfd   sp!,{r0,pc}
  ;end Start body
  .local:
        .local.lpwc     dw wc
        .local.lptitle  dw _title
        .local.lpwidth  dw width
        .local.lpheight dw height
  ;end pc relative locals of Start

WindowProc: ;proc WindowProc nospil uses[R4-R8,R11,LR},hwnd,wmsg,wparam,lparam
        stmfd   sp!,{r4-r8,r11,lr}
        cmp     a2,2
        moveq   r0,0
        bleq    PostQuitMessage
        moveq   r0,0
        ldmeqfd sp!,{r4-r8,r11,pc}
        cmp     a2,1
        bleq    .wmcreate
        apscall DefWindowProcW,r0,r1,r2,r3
        ldmfd   sp!,{r4-r8,r11,pc}
  .wmcreate:
        ldr     r6,[pc+Start.local.lpwc-$-8]
        mov     r1,r0
        ldr     r0,[r6,WNDCLASS.hInstance]
        mov     r2,$3E8
        bl      CommandBar_Create
        apscall CommandBar_AddAdornments,r0,0,0
        ldmfd   sp!,{r4-r8,r11,pc}
  ;end WindowProc body
  .local:
        .local.lpwc     dw wc
  ;end pc relative locals of WindowProc

section '.data' data readable writeable
        wc      WNDCLASS 1,WindowProc,0,0,0,0,0,5,0,_class
        _class  du 'FASMWINCE',0
        _title  du 'WinCE program template',0
        align 4
        width   dw ?
        height  dw ?

section '.idata' import readable writeable

        library coredll,'COREDLL.DLL',\
                commctrl,'commctrl.dll'
        include 'APICE\COREDLL.INC'
        include 'APICE\COMMCTRL.INC'    

for now it is mix of macroed & pure code

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 04 Jun 2018, 10:11
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 08 Jun 2018, 07:28
Question about ARM not relative to WinCE:
ARM_..._32 and ARM_..._64 are completely independent sets of instructions (like x86 & Intel64), or some instructions (maybe fpu ones) are subsetted (like x86 almost fully subset of AMD64).
registers in ARM32 are r with index, in ARM64 x with index.
Question about processor directive - Are some subsets of instructions are included in other subsets (v7 included in v8 or something else) or they completely independent subsets?
Post 08 Jun 2018, 07:28
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 08 Jun 2018, 10:58
For the 32 vs 64 modes, the instruction encoding is completely different. No overlap.of encoding anywhere. This is true for both the integer and floating point.

For fasmarm, the instruction sets enabled by the processor directive, and the coprocessor directive, do not overlap anywhere. You have to enable each one independently for your CPU.
Post 08 Jun 2018, 10:58
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< 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.