Jump to content
Tuts 4 You

[masm] - program won't run on Win7


DeadAndGone

Recommended Posts

DeadAndGone

hi all

a friend of me and i got a problem. we found a nice firework-effect for asm32.

but when trying to run the code in Windows 7 it crashes.

Maybe someone can help us to get a working firework-effect for winxp & win7 ?

pm me if you would take a look at the source

Edited by Silence
Link to comment

Hi Silence,

so did you check the used modules / APIs?Also check the source for possible used static addresses.Maybe you or your friend used some direct addresses into your ASM source like 402000 etc or maybe your firework effect need to run some special system add on which is maybe not installed on Win7.

Or just debug the file on win7 and check the exception where it does crash and analyze the code to see what was called / moved etc before.

Or just compile your source under win7 there you should get the error message in your program language if you try to run your source etc.

PS: You could also attach a exsample exe with your effect then we can also check the code to help you and find the reason.

greetz

Link to comment
DeadAndGone

well i dont have win7, so if you want to do a research here is example of it in the attach.

Edited by NotUsed
Link to comment

You are not saving/restoring registers properly. Procedures should always preserve ESI/EDI/EBP/EBX registers.

In your example, sub_4029BD, sub_40294E, sub_4024B0 and maybe few others failed to do that.

Link to comment
DeadAndGone

Yeah seems your right. I didn't coded it, but found trough google.

I don't know how to fix, just changing all the invalid register to the win32 ones?

If someone want to take a look at the source here it is:

Edited by NotUsed
Link to comment
DeadAndGone

Hi LCF-AT

Thanks for trying to help, but both files are not working.

My program uses ".686 & .mmx" instructionsset.

I need this to do this: cmovs eax,edx

So maybe this is the problem?

anyway I need to know why it doesnt work on Win7 and how to fix. Any ideas ? :)

Edited by Silence
Link to comment

Hi Silence,

ok I have no win7 can not check this problem exactly.

1. Your file used a ImageBase of 00400000

2. If you load your file with a other IB then it will not work so all addresses in code keep the same.

3. Try to add relocations in your source.

4. Try to load your original file in Olly with the IB of the original file 00400000 if you can.So if it get the IB of 00400000 with your file and if it then still not run / crash etc then there is a other problem so in that case try also to analyze the exception's which you get in Olly [disable all exceptions + skip exception in plugins if its enabled].Run the file and then you should break on any exception and check the code there.So the exception method is always a good way to find the reason of any crash problems.Just try this a little or just trace til the point where it crash and check or compare whats the diffrent there between XP & Win7 so you have both OS and you can do it. :)

EDIT: So if your 64 bit OS does not support xy instructions then you should get any error message about it like "command not supported or reconized" or?If not then just trace to the commands which bring the app to crash and try to use other commands if possible.

Ok or try this....patch this 2 routines to ret in Olly and then run and see whether it runs [now without effects].

Here patch both to ret.

0040103A  PUSH EBP                            
0040112C MOV EDI,DWORD PTR DS:[40D2CC]

greetz

greetz

Link to comment

Relocations mean nothing at all to execution, otherwise any older executables without them would fail to run on Windows 7, i'm not interested in AV or their issues i'm talking from an OS perspective.

To preserve registers on procedure calls, you can use the "uses" keyword when declaring your procedure, this way it will add a PUSH REG32 at the prelogue and POP REG32 at the epilogue code, you can put any registers you need: uses EBX EDX ESI EDI

[PROCEDURE_NAME] - PROC - [CALLING_CONVENTION] - [uSES_CONDITIONS] - [PARAMETERS]

For example, the random procedure trashes the EDX register, which may not make any difference but it used to be that EDX, EBX, ESI and EDI were preserved but it seems that EDX has become another scratch register so you need to make the choice yourself whether or not to save that one.


random PROC base:DWORD ; Park Miller random number algorithm
mov eax, seed ; from M32lib/nrand.asm
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov seed, ecx
div base
mov eax, edx
ret
random ENDP

to


random PROC [b][i]uses edx[/i][/b] base:DWORD ; Park Miller random number algorithm
mov eax, seed ; from M32lib/nrand.asm
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov seed, ecx
div base
mov eax, edx
ret
random ENDP

As i've stated, this particular procedure shouldn't be the one causing trouble but if you go through the source code and clean it up to preserve registers it might make a difference.

I've debugged the executable you provided and it crashes in:


lp3:
invoke FShell_render,[ebp+4],[ebp]
mov eax,GMode
mov ecx,offset FShell_explodeAG
mov ebx,offset FShell_explodeOS
test eax,eax
cmovz ecx,ebx
push [ebp+4]
call ecx
test eax,eax
jns @F
invoke random,maxy
push eax
mov eax,maxx
add eax,eax
invoke random,eax
mov edx,maxx
shr edx,1
sub eax,edx
push eax
push [ebp+4]
call FShell_recycle
@@:
mov eax,sb
add [ebp+4],eax
dec dword ptr[ebp]
jnz lp3

Looking at the code for FShell_recycle, the very first instruction trashes the EDI register without first preserving it and EBX suffers a similar fate a little further down:


FShell_recycle PROC hb:DWORD, x:DWORD, y:DWORD
mov edi,hb
mov eax,x
mov [edi+EXX],eax
mov eax,y
mov [edi+EXY],eax
mov eax,x
mov lightx,eax ; Light last one
mov eax,y
mov lighty,eax
mov eax,flash ; having only one light source
add eax,3200 ; 3200 million jouls...!
mov flash,eax ; add if previous lighting not extinguished
invoke random,20
inc eax
imul minlife
mov ebx,eax ; sync explosions by mouse clicks with rest
mov eax,[edi] ; by maintaining minimum delay of 'minlife'
xor edx,edx
idiv minlife
add edx,ebx
mov [edi],edx
invoke random,30 ; like its real world counterpart, creation process
add eax,10 ; is long and boring but the end product is explodin..
mov [esp-4],eax ; refer C++ source also. Most of the below area
mov eax,10000 ; is blind translation of that original C code
mov [esp-8],eax ; i crawled on that code as a Human C compiler...!
fld1
fild dword ptr[esp-4]
fidiv dword ptr[esp-8]
fsubp st(1),st(0)
fstp dword ptr[edi+AIR]
add edi,SPARC
fild y
fild x
mov eax,1000
mov [esp-4],eax
fild dword ptr[esp-4] ; 1000 (constant)
invoke random,maxpower
inc eax
mov [esp-4],eax
fild dword ptr[esp-4] ; power
mov ecx,nd
dec ecx
shl ecx,4
@@:
push ecx
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(2)
fdiv st(0),st(2)
fmul st(0),st(1)
mov ecx,[esp]
fstp dword ptr[edi+ecx+4]
fld st(0)
fmul st(0),st(0)
fld dword ptr[edi+ecx+4]
fmul st(0),st(0)
fsubp st(1),st(0)
fsqrt
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(3)
fdiv st(0),st(3)
fmulp st(1),st(0)
mov ecx,[esp]
fstp dword ptr[edi+ecx+12]
fld st(2)
fstp dword ptr[edi+ecx]
fld st(3)
fstp dword ptr[edi+ecx+8]
pop ecx
sub ecx,16
jnc @B
fcompp
fcompp
ret
FShell_recycle ENDP

Add the uses conditional to the start of the procedure:


FShell_recycle PROC [i][b]uses edi ebx[/b][/i] hb:DWORD, x:DWORD, y:DWORD
mov edi,hb
mov eax,x
mov [edi+EXX],eax
mov eax,y
mov [edi+EXY],eax
mov eax,x
mov lightx,eax ; Light last one
mov eax,y
mov lighty,eax
mov eax,flash ; having only one light source
add eax,3200 ; 3200 million jouls...!
mov flash,eax ; add if previous lighting not extinguished
invoke random,20
inc eax
imul minlife
mov ebx,eax ; sync explosions by mouse clicks with rest
mov eax,[edi] ; by maintaining minimum delay of 'minlife'
xor edx,edx
idiv minlife
add edx,ebx
mov [edi],edx
invoke random,30 ; like its real world counterpart, creation process
add eax,10 ; is long and boring but the end product is explodin..
mov [esp-4],eax ; refer C++ source also. Most of the below area
mov eax,10000 ; is blind translation of that original C code
mov [esp-8],eax ; i crawled on that code as a Human C compiler...!
fld1
fild dword ptr[esp-4]
fidiv dword ptr[esp-8]
fsubp st(1),st(0)
fstp dword ptr[edi+AIR]
add edi,SPARC
fild y
fild x
mov eax,1000
mov [esp-4],eax
fild dword ptr[esp-4] ; 1000 (constant)
invoke random,maxpower
inc eax
mov [esp-4],eax
fild dword ptr[esp-4] ; power
mov ecx,nd
dec ecx
shl ecx,4
@@:
push ecx
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(2)
fdiv st(0),st(2)
fmul st(0),st(1)
mov ecx,[esp]
fstp dword ptr[edi+ecx+4]
fld st(0)
fmul st(0),st(0)
fld dword ptr[edi+ecx+4]
fmul st(0),st(0)
fsubp st(1),st(0)
fsqrt
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(3)
fdiv st(0),st(3)
fmulp st(1),st(0)
mov ecx,[esp]
fstp dword ptr[edi+ecx+12]
fld st(2)
fstp dword ptr[edi+ecx]
fld st(3)
fstp dword ptr[edi+ecx+8]
pop ecx
sub ecx,16
jnc @B
fcompp
fcompp
ret
FShell_recycle ENDP

Go through the source and get all instances like that and see if that helps. Another option to consider is recoding it function at a time, cleaning it up as you go along and making it how you want/need it to be, which is what i would do seeing as it isn't a huge piece of code to begin with.

It will give more of an understanding of what the code is doing as well as ensuring that the code is error free and doesn't include another coders 'bad' habits.

Best of luck with this, i'm interested to see the effect myself so i may have a play with the source and see if i can do something with it, i'm running Windows 7 x64 so i can test it out as i go. I'll post anything i make here, with the source.

HR,

Ghandi

Link to comment

After preserving registers on function entry, the exe still crashes on the lp3: loop, the sixth call to FShell_render.

Judging by the content in the parameter passed to it, 0xABABABAB - 0xABABABAB, there is something not quite right...

Also, the global variable 'nb' is overwritten in the initialization loop, so the DEC DWORD PTR [EBP] will only ever reach 0x00 if the overwritten value is 0xFF, otherwise it loops more times than is necessary and looking at that, the sixth call to FShell_render crashes yet there are only 5 shells declared in the source code?

Here is a slightly edited version which seems to work, although i have not perused the code properly nor have i checked it for leaks or any other bugs. Pretty much all i did was add uses clauses to procedures that altered registers and then wrapped FireThread into its own PROC rather than being bare code and gave it local variables instead of using EBP naked.

The disclaimer by the original author still applies:

It is eyecandy-ware, no guarantee or warranty offered or implied and no responsibility for damages arising from use or misuse of the code/executable.

HR,

Ghandi

EDIT: Changed uploaded file, slightly cleaner code and such, uses local variables rather than temporary manual negative stack memory positions. Also has thread procedures wrapped in PROC statements, something which is a personal preference, nothing more.

I don't know what the author was talking about with utilizing 100% CPU, although i don't know what type of CPUs were available at its writing. My i7 registers between 0% and 1%, not even a tick on a single core monitor really, i wouldn't really expect that would change a great deal if it were taken to a dual core would it? I know some people still have old school CPUs but dual core is sort of entry level these days for personal use really, but i could be wrong too.

Firework.rar

Edited by ghandi
Link to comment

Hmmm, i'm using the same OS and i can't duplicate that problem, i have it maximized, minimized and custom sized using the edges and it doesn't crash or stutter at all.

HR,

Ghandi

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...