Log in

View Full Version : checking my ASM


tdennist
November 18th, 2004, 20:16
The task: make a trainer for the included Minesweeper game with Windows to stop the timer from advancing. I found the code address, and I made this program. However, it doesn't work .

Am I allowed to ask someone to look over my code and tell me what's wrong? In case I am (:-D):

Using Hutch's Masm32 8.2. The problem is that when I press the 'u' key, the program crashes. And SoftIce doesn't pop up, which is rather annoying. Keep in mind when you're reading this that I am really new at this, and this is my first attempt at a serious one of these type things. Don't make too much fun of me .
Code:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\kernel32.lib

WinMain proto WORD,WORD,WORD,WORD

.DATA
ClassName db "SimpleWinClass",0
AppName db "Window Name",0
char WPARAM 20h
winName db "Minesweeper",0 ; the name of the window
toWrite QWORD 909090909090h ; the bytes to write; 6 NOPs

.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?
IDProcess DWORD ? ; the ID of the process
tempHWnd HWND ? ; the window handle of the process
hProcess HANDLE ? ; eventually, the process to write to

.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax

invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess, eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShowWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND

mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx, NULL,\
ADDR ClassName,\
ADDR AppName,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
200,\
200,\
NULL,\
NULL,\
hInst,\
NULL
mov hwnd, eax
invoke ShowWindow, hwnd, CmdShow
invoke UpdateWindow, hwnd

.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax, msg.wParam
ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT

.IF uMsg == WM_DESTROY
invoke PostQuitMessage, NULL
.ELSEIF uMsg == WM_CHAR
push wParam
pop char
.IF char == 75h ;u
mov char,25h ;%
invoke InvalidateRect, hWnd, NULL, TRUE
call StopTime
.ELSE
invoke InvalidateRect, hWnd, NULL, TRUE
.ENDIF
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint, hWnd, ADDR ps
mov hdc,eax
invoke TextOut, hdc, 90,70, ADDR char, 1
invoke EndPaint, hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp

StopTime proc
invoke FindWindowA, NULL, ADDR winName ;get hWnd for Minesweeper
mov tempHWnd, eax ;put it into tempHWnd
invoke GetWindowThreadProcessId, tempHWnd, IDProcess ;get the process ID
invoke OpenProcess, PROCESS_ALL_ACCESS, FALSE, IDProcess ;open the process
mov hProcess, eax ;load the process handle into hProcess
invoke WriteProcessMemory, hProcess, 01002FF5h, ADDR toWrite, 6, NULL ;write the stuff
invoke CloseHandle, hProcess
StopTime endp
end start



Thanks.

Kayaker
November 18th, 2004, 21:01
Hiya,

Just like the other procs, your StopTime proc needs a 'ret', that should fix 'er up.

Cheers

tdennist
November 18th, 2004, 22:44
Thank you, that did indeed stop it from crashing.

Now, however, it just plain doesn't work. Do you see any other glaring mistakes? I don't even know if I used the proper procedure for getting the window handle, process ID, etc. Remember, this is my first ever attempt at this .

Also, the way I specified the bytes to write to the process seems stupid. Is a quad word the largest amount of bytes I can replace in the file at once? If there were more, would I have to save them in separate quad word variables? (And actually, I don't even know if I did it the right way. Help? )

Thanks.

edit: Also, forum mods and other gurus: tell me if I should edit my original post to not specify the game's name outright. I recall one of the forum rules being something about that....

Kayaker
November 19th, 2004, 01:54
Quote:
[Originally Posted by tdennist]edit: Also, forum mods and other gurus: tell me if I should edit my original post to not specify the game's name outright. I recall one of the forum rules being something about that....

Don't worry about Minesweeper! We can handle any MS goons that might complain

Because of a recent hand injury I can't type more than a few words here, so I'll leave the other questions to the ablebodied...

btw, you may want to read Zairon's reversing of Minesweeper at the main archive site,
http://woodmann.net/fravia/what_new.htm

bilbo
November 19th, 2004, 04:34
tdennist:
(1) first, be sure that the version you have of WINMINE.EXE really brings at address 0x1002FF5 the instruction you want to comment-out (you can check this with a debugger). This condition holds for windows XP version:
Code:
01002FF5 FF 05 9C 57 00 01 inc dword ptr ds:[100579Ch]

(2) second, check the name of Minesweeper window; in Windows 2000/XP the name is not Minesweeper, but it depends on the language of your installation, Correct it at winName location of your code

(3) finally, correct an error you made invoking GetWindowThreadProcessId.
The correct syntax is
Code:
invoke GetWindowThreadProcessId, tempHWnd, ADDR IDProcess

After these three steps, you can digit 'u' in your window and the timer will magically stop!

Quote:
[Originally Posted by tdennist]Is a quad word the largest amount of bytes I can replace in the file at once? If there were more, would I have to save them in separate quad word variables?

Not at all! You can declare them in plain bytes... Try to replace
Code:
toWrite QWORD 909090909090h
with
Code:
toWrite db 90h,90h,90h,90h,90h,90h

and the effects will not change.

Quote:
[Originally Posted by Kayaker]you may want to read Zairon's reversing of Minesweeper at the main archive site

LOL, he didn't make a deep reversing, since he misses the fact that the same effect could be reached with the XYZZY trick (google to find it) - joking... that's an instructive reading!

Kayaker:
Sorry for your wound... I hope you will be healthy again, and your brilliant brain has not suffered too

Regards, bilbo

ZaiRoN
November 19th, 2004, 06:28
Hi bilbo,
Quote:
he didn't make a deep reversing, since he misses the fact that the same effect could be reached with the XYZZY trick
Hmmm, you didn't read the initial minesweeper project in the mini project area

Best regards,
Zai

bilbo
November 19th, 2004, 08:02
Please, forgive me ZaiRoN, please...
After I got rid of the Ring, I have become more and more forgetful!
bilbo

ZaiRoN
November 19th, 2004, 08:20
Quote:
[Originally Posted by bilbo]Please, forgive me ZaiRoN, please...
Oh my good old hobbit, you are forgiven this time :P

JMI
November 19th, 2004, 11:17
Since surrendering the "One Ring" eventually saved Middle Earth, we can forgive an occasional failure of memory among the elder folk. That way I might also get away with a memory failure or three... uh ... what were we talking about?

Regards,

Kayaker
November 19th, 2004, 16:27
Quote:
[Originally Posted by bilbo]
Kayaker:
Sorry for your wound... I hope you will be healthy again, and your brilliant brain has not suffered too


Thank you, though I can't say I feel too f*ing brilliant today! ;-)
A few slowly typed cautionary observations about those Olfa "exacto" utility knives with the snap-off blades -

The blades can snap off at the most inopportune time.
They are *very* effective at filleting human flesh, quite reminiscent of cleaning a freshly caught fish actually...
They also sell stronger blades which don't snap off as easily. Now I know why.

Standard knife safety includes protecting ones exposed body parts to the consequences of an "expected" slip (taking into account such things as direction of push, possible angles of deflection, length of blade, how much you value the exposed body part(s), etc.)
Enhanced knife safety should include, where applicable, the consequences of a sudden shortening of blade length while remaining razor sharp.

If the thought "Maybe I shouldn't be doing this" ever crosses your mind while working with a knife, stop immediately and don't dismiss it.
'Close calls' are good to have every once in a while to make one appreciate how wonderful life is.
The realization that "it could have been a lot worse" is a wonderful thing.
Stitches(7) are a wonderful thing. So are flesh wounds that don't cut through tendons or major nerves.
Female doctors are especially attractive when stitching you up

Take care out there.

Cheers,
Kayaker

JMI
November 19th, 2004, 16:32
Kayaker:

Glad to hear you are healing up. Just wanted to know if the lady doc asked you to cough? And if so, were her hands cold?

Regards,

Kayaker
November 19th, 2004, 16:51
No, I was in an awkward position when working with the knife, not the doctor

tdennist
November 19th, 2004, 18:14
*cough* back on topic....;-).

Quote:
[Originally Posted by bilbo]
(2) second, check the name of Minesweeper window; in Windows 2000/XP the name is not Minesweeper, but it depends on the language of your installation, Correct it at winName location of your code


Ok, here's where I feel stupid. Is the name of the windows the text in the title bar? Because if it is, Minesweeper is the right name....

Thanks.

(edit: I swear, once I learn this stuff, I'm writing a bunch of well written tutorials, explaining step by step and skipping nothing on how to do simple things. Like make a trainer for Minesweeper.)

Silver
November 20th, 2004, 09:12
tdennist, easiest way to check window and window class names (there is a difference) is by using the spy++ tool that Microsoft ship with Visual Studio (and I think it's on their site for freedownload, and in Resource Kit's etc).

klier
November 20th, 2004, 09:37
...or use windowjuggler plugin for olly.
Regards,

tdennist
November 20th, 2004, 17:29
Yay! Thanks, guys. It works now! Now, my next question is, how should I start going about changing it so that I don't have to press 'u' inside my application window? I.e. a hotkey that will work from any application.

dELTA
November 20th, 2004, 20:26
Look into global hooks in Windows, especially the API function SetWindowsHookEx...

tdennist
November 21st, 2004, 21:50
Well, I read up on that stuff, and then today, while browsing Iczelion's Win32 assembly page I found this site:

http://spiff.tripnet.se/~iczelion/Win32Api1.htm

Which explains how to create a hotkey. I put it into my Minesweeper game and it works just dandily. Does this solution work? In other words, is it a crappy workaround and should I look into the Windows hooks? Or should I just be happy with this and keep using it?

dELTA
November 22nd, 2004, 08:05
As long as your own program has any windows, the RegisterHotKey-stuff will work just fine for simple uses. The hooks are more versatile and work without the need to have your own window though.

tdennist
November 22nd, 2004, 17:27
In what way are they more versatile? And when would I have an occasion to create an application that doesn't have a window? The only instance I can think of would be a keylogger, but I don't really have much need to create one of those .

bilbo
November 23rd, 2004, 02:30
We are slipping in a philosophical disquisition, aren't we?
Regards, bilbo

dELTA
November 24th, 2004, 10:11
The generic hooks are more versatile because they can capture much more things than simple key-combinations, like for example mouse clicks and key combinations like "if the user first presses this, then that, and then this", and many even more advanced things. But as I said, for simple key combinations in windowed apps, the simpler technique is pretty ok too.

Btw, I'm not sure if they behave differently under full screen DirectX apps either, they might...

Silver
November 24th, 2004, 12:29
Did somebody say DirectX?

What my esteemed colleague dELTA meant when he said "full screen DirectX apps" was actually, "It makes no difference to a keyboard, mouse or any other input device hook if a D3D app is running in windowed or fullscreen mode, however if DirectInput is being used to manage user input a side effect is that any relevant hooks *usually* don't work"

Basically, D3D is the drawing part of DX, DInput is the input handling part. If you acquire an input device using DInput it's normally handled at a <insert respectful metal-bashing hush here> lower level than normal (ie: direct from device/driver level). There are different ways of acquiring devices, nominally referred to as the "cooperation level" between DInput and the rest of Windows. Depending on a number of factors (including DInput config via the control panel applet and the cooperation level) input hooks usually won't work. There is absolutely no requirement to use DInput to get user input for D3D apps - personally I've coded D3D apps that used normal win32 WM_ for their input, that used WM_ for keyboard and DInput for mouse, and vice versa. So I guess what that rambling is trying to say is, just because an app uses D3D for gfx doesn't mean it uses DInput for input.

This is an interesting article about a similar issue: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dninput/html/nodelaydirectinput.asp
In essence, when you code a DInput app there is an annoying lag in keyboard/mouse input when debugging. It's caused by the same problem.

I'm such a DX geek

nikolatesla20
November 24th, 2004, 13:03
What a nerd

-nt20

dELTA
November 24th, 2004, 20:56
As we all know, mind reading is a main requirement to be accepted into the higher levels of this community, and Silver did a good job as always, yeah, that's exactly what I meant.

Btw, Silver, can a D3D app in windowed mode use DirectInput like that too? In that case I guess it must be disabled as soon as the window of the D3D app loses focus at least, to make all the other apps work normally? That's what caused me to suspect that only "some full screen DirectX apps" (i.e. the ones using DirectInput) could be causing problems like that.

Silver
November 25th, 2004, 06:02
Quote:
can a D3D app in windowed mode use DirectInput like that too? In that case I guess it must be disabled as soon as the window of the D3D app loses focus at least, to make all the other apps work normally?


It sure can. DInput will work regardless of fullscreen or windowed. I think the main reason this isn't immediately apparent is that nobody plays games windowed, so the only way you'd know DInput can do this is during development (unless you do remote or dual monitor debugging, it's basically impossible to debug a D3D app running full screen so everything is done windowed).

DInput in windowed mode is all about the cooperation level. The normal effect, however, is that the mouse etc are "locked" to the window and because they're handled at a lower level than normal you can't pre-emptively disable them through DInput as such, you can only react to losing them. Losing focus ("lost device" with a DX app is a nightmare issue I won't go into detail here. Lost devices give all newbie DX coders nightmares. In essence, every iteration of the render and input loop in a DX app you absolutely must validate your devices. You need to make sure you still have access to all the devices represented by your COM objects, and if you don't, go into a testing process to try to reacquire them. This is true for DInput and D3D (if you're interested, look at IDirect3DDevice9::TestCooperativeLevel() ). If you lose a device then reacquire it, you have to reload all your unmanaged resources associated with the device (such as texture resources not created in the managed memory pool).

Damn, I said I wouldn't get into it . It's simple enough to understand if you have a basic understanding of DX process, it's the implementation that's awkward. Let me know (or start a new post) if you'd like a better explanation.

Does that answer your question?

dELTA
November 25th, 2004, 07:57
Hehe, an interesting insight into the wonders of DX as always, I'm already looking forward to the next one. And yeah, sure, that answers my question just fine (and my next couple of questions too).