crashdemons Posted June 10, 2009 Share Posted June 10, 2009 (edited) This was originally posted as an example for This Question, until I moved it here as an example.Requirements: Windows XP MinesweeperMemory Editing Options:Set/Lock time elapsed (Lock meaning continually reset here)One mine mode** (Only creates one mine on the field; standard minimum is 10)Right-click to win** (Every square is occupied by a mine; right-click wins)Edit the "Best Times" records.(* = Takes effect on the NEXT game; ** = Also all subsequent games)Other:The script will check the file version/size of winmine.exe to determine if it is compatible, and warn you if not. A hash might actually be more efficient though.Notes: you can undo "One Mine" and "Right-Click-Win" modes by resetting the values with the "Custom" menu in Minesweeper - since I didn't offer a direct method of editing the values.This was based on my own findings of minesweeper and the script that w0uter wrote back in 2005.If there's any official problem with editing the memory of this product, I'll happily stop.I should be using something like NomadMemory I guess, but I'll worry about it later.expandcollapse popup#include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global Const $MEM_O = 0x8 Global Const $MEM_R = 0x10 Global Const $MEM_W = 0x20 Global $sProcessName='winmine.exe' Global $WinMinePath=@SystemDir&'\winmine.exe' Global $WinMineSize=119808 Global $WinMineVers='5.1.2600.0' Global $aLockText[2]=['Lock Value','Unlock Value'] Global $fLockElapsed=False If Not FileExists($WinMinePath) Then Exit(MsgBox(16,'MineSweeper Trainer','Error: Winmine.exe was not found during file verification.')) If Not (FileGetSize($WinMinePath)=$WinMineSize And FileGetVersion($WinMinePath)=$WinMineVers) Then Global $iContinue=MsgBox(32+4,'Minesweeper Trainer','Your Minesweeper version is not compatible with this program.'&@CRLF&' It is suggested that you discontinue use of this program to avoid damaging the program process.'&@CRLF&@CRLF&'Do you want to continue anyway?') If Not ($iContinue=6) Then Exit EndIf _CheckProcess(); just to make sure it's running before we do anything Opt("GUIOnEventMode", 1) #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("MineSweeper 5.1 Trainer - By CrashDemons", 361, 156+20, 192, 124) GUISetOnEvent(-3,'GUIOnEvent_Close') $Input1 = GUICtrlCreateInput("0", 85, 0, 96, 21, BitOR($ES_AUTOHSCROLL,$ES_NUMBER)) GUICtrlSetLimit(-1, 3) $Label1 = GUICtrlCreateLabel("Time Elapsed: ", 2, 3, 77, 17) $Button1 = GUICtrlCreateButton("Set Value", 182, 0, 72, 21, $WS_GROUP) GUICtrlSetOnEvent(-1,'GUICtrlOnEvent_SetElapsed') $Button2 = GUICtrlCreateButton("Lock Value", 255, 0, 101, 21, $WS_GROUP) GUICtrlSetOnEvent(-1,'GUICtrlOnEvent_LockElapsed') $Button4 = GUICtrlCreateButton("Only 1 mine (on New Game)", 182, 20, 356-182, 21, $WS_GROUP) GUICtrlSetOnEvent(-1,'GUICtrlOnEvent_SetOneMine') $Button5 = GUICtrlCreateButton("Right-click win (on New Game)", 0, 20, 356-182, 21, $WS_GROUP) GUICtrlSetOnEvent(-1,'GUICtrlOnEvent_SetAllMines') $Group1 = GUICtrlCreateGroup("Fastest Minesweeper Times", 2, 24+20, 354, 129) $Label2 = GUICtrlCreateLabel("Beginner: ", 18, 49+20, 52, 17) $Input2 = GUICtrlCreateInput("0", 114, 46+20, 70, 21, BitOR($ES_AUTOHSCROLL,$ES_NUMBER)) GUICtrlSetLimit(-1, 3) $Label5 = GUICtrlCreateLabel("seconds", 189, 49+20, 44, 17) $Input3 = GUICtrlCreateInput("Anonymous", 247, 45+20, 100, 21, $ES_AUTOHSCROLL) GUICtrlSetLimit(-1, 32) $Label3 = GUICtrlCreateLabel("Intermediate: ", 18, 76+20, 68, 17) $Input4 = GUICtrlCreateInput("0", 114, 73+20, 70, 21, BitOR($ES_AUTOHSCROLL,$ES_NUMBER)) GUICtrlSetLimit(-1, 3) $Label4 = GUICtrlCreateLabel("seconds", 189, 76+20, 44, 17) $Input5 = GUICtrlCreateInput("Anonymous", 247, 72+20, 100, 21,$ES_AUTOHSCROLL) GUICtrlSetLimit(-1, 32) $Label6 = GUICtrlCreateLabel("Expert: ", 18, 102+20, 40, 17) $Input6 = GUICtrlCreateInput("0", 114, 99+20, 70, 21, BitOR($ES_AUTOHSCROLL,$ES_NUMBER)) GUICtrlSetLimit(-1, 3) $Label7 = GUICtrlCreateLabel("seconds", 189, 102+20, 44, 17) $Input7 = GUICtrlCreateInput("Anonymous", 247, 98+20, 100, 21, $ES_AUTOHSCROLL) GUICtrlSetLimit(-1, 32) $Button3 = GUICtrlCreateButton("Set Values", 247, 125+20, 100, 21, $WS_GROUP) GUICtrlSetOnEvent(-1,'GUICtrlOnEvent_SetScores') GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 If $fLockElapsed Then _WriteProcess(_CheckProcess(),0x0100579C,Int(GUICtrlRead($Input1)),4) Sleep(300) WEnd Func GUIOnEvent_Close() Exit EndFunc Func GUICtrlOnEvent_SetElapsed() _WriteProcess(_CheckProcess(),0x0100579C,Int(GUICtrlRead($Input1)),4) EndFunc Func GUICtrlOnEvent_LockElapsed() GUICtrlSetState($Button2,$GUI_DISABLE) $fLockElapsed=Not $fLockElapsed Switch $fLockElapsed Case True ;locked GUICtrlSetState($Input1,$GUI_DISABLE) GUICtrlSetState($Button1,$GUI_DISABLE) GUICtrlSetData($Button2,$aLockText[1]) Case False ;unlocked GUICtrlSetState($Input1,$GUI_ENABLE) GUICtrlSetState($Button1,$GUI_ENABLE) GUICtrlSetData($Button2,$aLockText[0]) EndSwitch GUICtrlSetState($Button2,$GUI_ENABLE) EndFunc Func GUICtrlOnEvent_SetScores() GUICtrlSetState($Button3,$GUI_DISABLE) ; I *REALLY* don't want to have to bother with disabling this entire section of the form Local $Score1=Int(GUICtrlRead($Input2)) Local $Score2=Int(GUICtrlRead($Input4)) Local $Score3=Int(GUICtrlRead($Input6)) Local $Name1=GUICtrlRead($Input3) Local $Name2=GUICtrlRead($Input5) Local $Name3=GUICtrlRead($Input7) _WriteProcess(_CheckProcess(),0x010056CC,$Score1,4) _WriteProcess(_CheckProcess(),0x010056D0,$Score2,4) _WriteProcess(_CheckProcess(),0x010056D4,$Score3,4) Local $nul=Chr(0) $Name1=StringToBinary($Name1&$nul,2) $Name2=StringToBinary($Name2&$nul,2) $Name3=StringToBinary($Name3&$nul,2) _WriteProcess(_CheckProcess(),0x010056D8,$Name1,BinaryLen($Name1)) _WriteProcess(_CheckProcess(),0x01005718,$Name2,BinaryLen($Name2)) _WriteProcess(_CheckProcess(),0x01005758,$Name3,BinaryLen($Name3)) GUICtrlSetState($Button3,$GUI_ENABLE) EndFunc Func GUICtrlOnEvent_SetOneMine() ;0x010056A4 is the number of mines to place - which you can normally change on custom games (winmine GUI minimum is 10) _WriteProcess(_CheckProcess(),0x010056A4,1,4) EndFunc Func GUICtrlOnEvent_SetAllMines() Local $w=Execute(_ReadProcess(_CheckProcess(), 0x01005334, 1));cols currently drawn Local $h=Execute(_ReadProcess(_CheckProcess(), 0x01005338, 1));rows currently drawn (We'll assume this is below 255) Local $MaximumMines=$w*$h _WriteProcess(_CheckProcess(),0x010056A4,$MaximumMines,4) EndFunc Func _CheckProcess() Local $pid=ProcessExists($sProcessName) If $pid=0 Then Switch MsgBox(32+4,'Minesweeper Trainer','Minesweeper does not appear to be running.'&@CRLF&@CRLF&'Do you want to start it?') Case 6 $pid=Run($WinMinePath) Case Else If $fLockElapsed Then GUICtrlOnEvent_LockElapsed() EndSwitch EndIf Return $pid EndFunc Func _WriteProcess($pid,$address,$value,$length) If $pid=0 Then Return $v_Open = _MemOpen($MEM_W + $MEM_O, False, $pid) $v_Read = _MemWrite($v_Open, $address, $value, $length) $v_Close = _MemClose($v_Open) EndFunc Func _ReadProcess($pid,$address,$length) If $pid=0 Then Return $v_Open = _MemOpen($MEM_R+$MEM_O ,False, $pid) $v_Read = _MemRead($v_Open, $address, $length) $v_Close = _MemClose($v_Open) Return $v_Read EndFunc Func _MemOpen($i_dwDesiredAccess, $i_bInheritHandle, $i_dwProcessId) $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', $i_dwDesiredAccess, 'int', $i_bInheritHandle, 'int', $i_dwProcessId) If @error Then SetError(1) Return 0 EndIf Return $ai_Handle[0] EndFunc ;==> _MemOpen() Func _MemRead($i_hProcess, $i_lpBaseAddress, $i_nSize, $v_lpNumberOfBytesRead = '') Local $v_Struct = DllStructCreate ('byte[' & $i_nSize & ']') DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $i_hProcess, 'int', $i_lpBaseAddress, 'int', DllStructGetPtr ($v_Struct, 1), 'int', $i_nSize, 'int', $v_lpNumberOfBytesRead) Local $v_Return = DllStructGetData ($v_Struct, 1) $v_Struct=0 Return $v_Return EndFunc ;==> _MemRead() Func _MemWrite($i_hProcess, $i_lpBaseAddress, $v_Inject, $i_nSize, $v_lpNumberOfBytesRead = '') Local $v_Struct = DllStructCreate ('byte[' & $i_nSize & ']') DllStructSetData ($v_Struct, 1, $v_Inject) $i_Call = DllCall('kernel32.dll', 'int', 'WriteProcessMemory', 'int', $i_hProcess, 'int', $i_lpBaseAddress, 'int', DllStructGetPtr ($v_Struct, 1), 'int', $i_nSize, 'int', $v_lpNumberOfBytesRead) $v_Struct=0 Return $i_Call[0] EndFunc ;==> _MemWrite() Func _MemClose($i_hProcess) $av_CloseHandle = DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $i_hProcess) Return $av_CloseHandle[0] EndFunc ;==> _MemClose() Edited June 10, 2009 by crashdemons My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.) Link to comment Share on other sites More sharing options...
Inverted Posted June 10, 2009 Share Posted June 10, 2009 Tested and it works fine on XP, cool. I'll check out your memory functions when I get some time. I got to improve my DllCall+winapi understanding. Link to comment Share on other sites More sharing options...
crashdemons Posted June 10, 2009 Author Share Posted June 10, 2009 (edited) They're not my memory functions, I stole them from w0uter. (as per my note) But I'd like to know what the advantages and disadvantages of using NomadMemory or a different memory UDF is. The current memory functions fine for me - and unless someone can provide issue with it, there's not alot of a reason to change it. There are other edits available in minesweeper, but some of the other values either aren't important enough to edit or are hard to track down. And, as with minesweeper, if you have a program where you can see a unique value and see when it changes, or you can change an unknown value on-demand while using the program regularly - you can usually track down and change it in a method such as this. Eg: there are memory edits available for Freecell, Spider Solitaire, etc. (and of course more advanced games) By the way, why did Koda add the WS_GROUP style to the button controls? - I don't see the necessity unless I'm missing something. Edited June 10, 2009 by crashdemons My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.) Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now