flat assembler
Message board for the users of flat assembler.

Index > Windows > Dll wont load on vista 64

Author
Thread Post new topic Reply to topic
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
I'm having trouble using some of my 32 bit programs on vista 64.
i wrote the following DLL for generating 32 bit random numbers but when i try to use it on vista 64 it always crashes before it even gets to the dll.
Does anyone know why?

Code:
;my implementation of the
;Mersenne Twister Random algorthim
;by FrozenKnight

;call mt_init with a seed value to set up random
;call mt_random to get random value (note if you dont set it up it will set it's self up)
;also note that it uses shared memory so that the algorthim doesnt require to be set up a second time
;when mupital applications are using it.

format PE GUI 4.0 DLL
entry  DllStart

section '.edata' export data readable

dd 0,\                  ;Characteristics
   45984F00h                ;TimeDateStamp
dw 0,\                       ;MajorVersion
   1                   ;MinorVersion
dd RVA _szDllName,\   ;Name
   100,\              ;Base
   5,\                        ;NumberOfFunctions
   5,\                   ;NumberOfNames
   RVA _FuncAddrs,\  ;AddressOfFunctions
   RVA _NameAddrs,\     ;AddressOfNames
   RVA _OrdinalsAddrs        ;AddressOfNameOrdinals


_FuncAddrs:    ;must match sorted according to ordeal order
dd RVA MTRand
dd RVA MTinitMan;MTinit
dd RVA rand
dd RVA srand
dd RVA r4d6m1

_NameAddrs:    ;must be sorted
dd RVA _szMTinit
dd RVA _szMTRand
dd RVA _szr4d6m1
dd RVA _szrand
dd RVA _szsrand

_OrdinalsAddrs: ;must start at 0 and count up
dw 1               ;must match NameAddr order
dw 0
dw 4
dw 2
dw 3

_szDllName    db 'RAND.DLL', 0
_szMTRand db 'MTrand',0
_szMTinit    db 'MTinit',0
_szr4d6m1    db 'r4d6m1',0
_szrand      db 'rand',0
_szsrand       db 'srand',0


section '.text' code readable executable

align 8
DllStart:
;  call MTRand
;  call MTRand
;  call MTRand
;  call MTRand
  retn 4

align 8
srand:
  pop  eax
  pop    [_seed]
  jmp        eax


;this is a simple linear random function Primes gatehred from the rand function provided by the MSVC compiler
align 8
rand:
  mov eax, [_seed]
  mov edx, 214013
  mul edx
  add eax, 2531011
  shr eax, 16
  and eax, 7FFFh
  mov [_seed], eax
  ret

db 'FrozenKnight - If you use this please give me credit. ',\
   'i worked hard to get this to execute as fast as i could. Thank You.', 0

align 8
MTinitMan:
  mov         dword [mt_location], 623
align 8
MTinit:
  mov     [mt_initlized], 1
  mov      eax, [esp+4]
  mov   [mt_buffer], eax
  push      esi
  push   ecx
  push   edx
  mov    edx, 1
  mov         eax, mt_buffer
@@:
  mov      ecx, [eax]
  mov     esi, ecx
  shr       esi, 1Eh
  xor       esi, ecx
  imul      esi, 6C078965h
  add         esi, edx
  mov       [eax+4], esi
  add   eax, 4
  inc         edx
  cmp    eax, mt_buffer + (623*4)
  jl        @b
  pop     edx
  pop    ecx
  pop    esi
  retn   4

align 8  ;alignments used to speed up calls and jumps.
MTRand:
  push        ebx
  push   edx
  mov    ebx, mt_location
  dec       dword [ebx]
  js     .reseed
 .return:
  mov       eax, [ebx]
  ;---interlock---
  mov       eax, [mt_buffer+eax*4]
  ;---interlock---
  mov   ebx, eax
  ;---interlock---removed by changeing following ebx to eax

  sar    eax, 0Bh
  ;---interlock---
  xor         eax, ebx
  ;---interlock---
  mov         ebx, eax

  shl   eax, 7
  ;---interlock---
  and   eax, 0FF3A58ADh; 09D2C5680h
  ;---interlock---
  xor      eax, ebx
  ;---interlock---
  mov         ebx, eax

  shl   eax, 0Fh
  ;---interlock---
  and         eax, 0FFFFDF8Ch; 0EFC60000h
  ;---interlock---
  xor      eax, ebx
  ;---interlock---
  mov         ebx, eax

  sar   eax, 12h
  ;---interlock---
  xor         eax, ebx

  pop   edx
  pop    ebx                        
  retn

align 8
 .init:       ;i use a neat trick here that allows me to save
  rdtsc      ;a few cycles when calling these functions by allowing
  push      eax       ;the ruteen to return from it's call at a diffrent location
  push        .return
  jmp        MTinit
align 8
 .reseed:
  mov     eax, [mt_initlized]
  mov    dword [ebx], 623
  test      eax, eax
  jz        .init

  push     edi
  push   ebx
  push   ecx
  mov    edi, mt_buffer
  mov         ebx, mt_lookup
  push        dword [edi]
 .loop:
  cmp     edi, mt_buffer + (622 * 4)
  mov     ecx, [edi]
  jg      .final
  mov         edx, [edi+4]
  and   ecx, 80000000h
  and         edx, 7FFFFFFFh
  or          edx, ecx
  mov       ecx, edx
  mov       eax, [ebx]
  and     edx, 1
  shr         ecx, 1
  lea         edi, [edi+4]
  xor   ecx, [eax]
  lea     ebx, [ebx+4]
  xor   ecx, [mag01+edx*4]
  mov     [edi-4], ecx
  jmp   .loop
align 8
 .final:
  pop       edx
  and    eax, 80000000h
  and         edx, 7FFFFFFFh
  or          edx, eax
  mov       eax, [ebx]
  mov     ecx, edx
  and       edx, 1
  shr         ecx, 1
  ;---interlock---
  xor   ecx, [mt_buffer + 396*4]
  ;---interlock---
  xor         ecx, [mag01+edx*4]
  mov     [edi], ecx
  pop     ecx
  pop    ebx
  pop    edi
  jmp    .return

r4d6m1:
  push  ecx
  mov    ecx, [esp + 4*2]
  and       ecx, 0FFFFh
  mov    eax, 18
  cmp        ecx, 64473
  jg      .exit
  dec  eax
  cmp    ecx, 61742
  jg      .exit
  dec  eax
  cmp    ecx, 56989
  jg      .exit
  dec  eax
  cmp    ecx, 50365
  jg      .exit
  dec  eax
  cmp    ecx, 42274
  jg      .exit
  dec  eax
  cmp    ecx, 33577
  jg      .exit
  dec  eax
  cmp    ecx, 25132
  jg      .exit
  dec  eax
  cmp    ecx, 17648
  jg      .exit
  dec  eax
  cmp    ecx, 11479
  jg      .exit
  dec  eax
  cmp    ecx, 6877
  jg       .exit
  dec  eax
  cmp    ecx, 3742
  jg       .exit
  dec  eax
  cmp    ecx, 1820
  jg       .exit
  dec  eax
  cmp    ecx, 759
  jg        .exit
  dec  eax
  cmp    ecx, 253
  jg   .exit
  dec       eax
  cmp    ecx, 51
  jg .exit
  dec  eax
.exit:
  pop      ecx
  ret    4*1

section '.rdata' data readable ;writeable shareable
 ;N = 624
 ;M = 397
 mt_lookup:
  rept 227 kk
  {
    dd ((kk-1)+397)*4+mt_buffer
  }
  rept 397 kk
  {
    dd (kk-1)*4+mt_buffer
  }
; rolllookup:
;  dd 64473, 18
;  dd 61742, 17
;  dd 56989, 16
;  dd 50365, 15
;  dd 42274, 14
;  dd 33577, 13
;  dd 25132, 12
;  dd 17648, 11
;  dd 11479, 10
;  dd 6877,  9
;  dd 3742,  8
;  dd 1820,  7
;  dd 759,   6
;  dd 253,   5
;  dd 51,    4
;  dd 0,     3


section '.data' data readable writeable shareable
  ;UPPER_MASK    dd  0x80000000
  ;LOWER_MASK    dd  0x7fffffff

  mag01        dd  0
               dd  09908B0DFh

  mt_initlized    dd  0
  mt_location  dd  0 ;start at 0 location

  mt_buffer    dd    624 dup (?) ;mt seed values

  _seed        dd    ? ;MS rand seed values


section '.reloc' fixups data discardable    
Post 22 Apr 2009, 19:08
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Shouldn't you use "mov eax, 1" on DllStart before returning? Also, it is "retn 12" not four.

Don't know if you made the export table correctly, try using the export macro if after fixing DllStart you still don't get it working correctly.
Post 22 Apr 2009, 19:19
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
Thank you.
Just 1 question what are the other 8 bytes for i thought dll's only had 1 parameter.
Post 22 Apr 2009, 22:55
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
This comes from the EXAMPLES folder of the fasm's Windows package:
Code:
; DLL creation example

format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'

section '.text' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov     eax,TRUE
        ret
endp

; VOID ShowErrorMessage(HWND hWnd,DWORD dwError);

proc ShowErrorMessage hWnd,dwError
  local lpBuffer:DWORD
        lea     eax,[lpBuffer]
        invoke  FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0
        invoke  MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
        invoke  LocalFree,[lpBuffer]
        ret
endp

; VOID ShowLastError(HWND hWnd);

proc ShowLastError hWnd
        invoke  GetLastError
        stdcall ShowErrorMessage,[hWnd],eax
        ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

  import kernel,\
         GetLastError,'GetLastError',\
         SetLastError,'SetLastError',\
         FormatMessage,'FormatMessageA',\
         LocalFree,'LocalFree'

  import user,\
         MessageBox,'MessageBoxA'

section '.edata' export data readable

  export 'ERRORMSG.DLL',\
         ShowErrorMessage,'ShowErrorMessage',\
         ShowLastError,'ShowLastError'

section '.reloc' fixups data discardable
    

(Remember that "ret" under a proc context is a macro and is replaced by "retn args_size")

DllMain
Post 22 Apr 2009, 23:05
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
Thank you, i wonder why that the orig will work under win xp 32?
Post 23 Apr 2009, 08:41
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Well is possible, for instance you can make WindowProc wrong and will work in XP while it will crash on Windows 98. However, I see that your original code called several times a function, perhaps that was making it work because it set EAX to a non-zero value and then the caller of DllMain was immune to the stack unbalancing error. Actually there are situations in which the callee won't make any problem, for example this:

Code:
push ebp
mov ebp, esp
.
.
.
push 3
push 2
push 1
call callee_that_does_ret_4_instead_of_ret_12
; ESP unbalanced here
leave ; Now thanks to EBP, ESP will have the correct value once more
ret    


As long as the caller has an EBP-Based frame and don't use ESP it is OK. But implicit use of ESP should be taken into consideration too, if there is a PUSH before calling then the POP will restore garbage.

So, in conclusion, returning in the wrong way doesn't mean that will crash at any situation but yet you are opening the chance so it is better to do it right since that is what the caller is expecting and the times the application survives are just by "miracle".

Yes, I'm missing some situation like, for instance, stack overflow caused by the repeated call to a function that returns incorrectly. I just won't enumerate all the possible outcomes.
Post 23 Apr 2009, 15:06
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-2020, Tomasz Grysztar.

Powered by rwasa.