Reading Program Memory In AHK - memory

So I am working on a program to read values from a game (Mitos.is: The Game).
It is similiar to Agar.io
You have a size (mass), and I want to get the mass amount, it is a program, not an online game like Agar.io.
I have found this Auto Hotkey script:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
ReadMemory(MADDRESS=0,PROGRAM="",BYTES=4)
{
Static OLDPROC, ProcessHandle
VarSetCapacity(MVALUE, BYTES,0)
If PROGRAM != %OLDPROC%
{
WinGet, pid, pid, % OLDPROC := PROGRAM
ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
,"Int",16,"Int",0,"UInt",pid) : 0)
}
If (ProcessHandle) && DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",BYTES,"UInt *",0)
{ Loop % BYTES
Result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
Return Result
}
return !ProcessHandle ? "Handle Closed:" closed : "Fail"
}
mass := ReadMemory(Address here, "Mitos.is: The Game")
MsgBox, %mass%
It works seamlessly but there is one slight problem, in Cheat Engine I took the liberty of finding the base address as shown below:
So I took the address circled here:
And inserted that into the program where it says "Address Here", correct me if this is not the right address, but when I restart the game and run my script it says "Fail", but in Cheat Engine the address is still valid. Help?

Check the address if it changes after restarting the game, or do not restart game just run the script without restart and you haven't defined bytes so try following,
ReadMemory(MADDRESS=0, PROGRAM="", BYTES=4 )
mass := ReadMemory("0x123456", "Mitos.is: The Game", "4")
"PROGRAM" should be correct window title use spy to get correct window title, address has to be in hex value i.e. "0x15B29DD0", I don't know how your cheat engine reads program memory address.

Related

How to store AccountBalance() into a variable?

if(Total_sell_pos() == 0 && Total_buy_pos() == 0) {
double previous_balance = AccountBalance(); //usd1000
}
if (AccountEquity() > previous_balance + (previous_balance *0.05)){ //usd1000 + 50 = usd1050
CloseSellOrders();
CloseBuyOrders();
Delete_Pendings();
}
if Equity more than usd1050 then delete pending and orders.
But why when run the code, it keep delete pending and orders immediately even when Equity is less than previous balance?
The following code is the problem, and I replace it :
AccountEquity() > previous_balance + (previous_balance *0.05)
with
AccountEquity() > 1050
then only it works. I did try to check the value :
double check_value = previous_balance + (previous_balance *0.05);
printf (check_value); //1050
May I know why I cannot use the following code?
AccountEquity() > previous_balance + (previous_balance *0.05)
Q: How to store AccountBalance() into a variable?
Let's start with the variable - declare it:
double aPreviousBALANCE;
The scope-of-declaration is driven by the enclosing code-block boundaries. MQL4/5 can declare a variable on the "global"-scope, that may become visible from inside other code-blocks, but if any such has a variable name identical to the "global"-scope defined one, the locally declared ( explicitly in the code, or introduced from the function-parameters' declaration in the call-signature specification ) will "shade-off" the access to the variable declared on the "global"-scope. This you have to check in the original code and MQL4/5-IDE may warn you about such collision(s) during the compilation ( ref. Compiler Warning Messages ).
Let's store in it the actual state, we'll have more steps here:
RefreshRates(); // Force a state-update
aPreviousBALANCE = AccountInfoDouble( ACCOUNT_BALANCE ); // Store an updated value
Q: May I know why I cannot use the following code?
Well, any language, MQL4/5 not being an exception, has some order of execution of mathematical operators. MQL4 need not and does not have the warranty about using the same one as any other language we may have had some prior experience. So, always be rather explicit in this a specify all ordering via explicit parentheses, this will save you any further "surprises" when the language parser / compiler will suddenly change the priority of operators and sudden nightmares will appear. Not worth a single such shock to ever happen:
if ( ( ( a * b ) + c ) < fun() ) // is EXPLICIT and a way safer, than
if ( a * b + c < fun() ) // is DEPENDENT on not having {now|in future}
// a binary boolean (<)-operator
// a higher priority than (+)-op
so, rather be always explicit and you remain on the safer side.
Finally, test:
RefreshRates(); // Force a state-update
if ( ( aPreviousBALANCE * 1.05 ) < AccountInfoDouble( ACCOUNT_EQUITY ) )
{
...
}
Also check, how are your settings pre-set from the Broker-side - they run a Support-Line for you to ask about their settings:
Equity calculation depends on trading server settings.
Print( "Profit calculation mode for SYMBOL[ ",
Symbol(),
" ] is ",
MarketInfo( Symbol(), MODE_PROFITCALCMODE ),
" { 0: mode-FOREX, 1: mode-CFD, 2: mode-FUTURES }."
);
And where is my AccountBalance() function?
Recent Terminal Builds use a set of new types of calls to:
AccountInfo{Integer|
Double|
String}( <anEnumDrivenItemIDENTIFIER>
)
SymbolInfo{Integer|
Double|
String}( <aSymbolNAME>,
<anEnumDrivenItemIDENTIFIER>
)
to name just a few, so re-read the documentation to adopt the most recent changes. Always. ALAP when your Terminal has got a new Build updated ( might be seen when loading a new version of Help files for the MQL4-IDE and/or Terminal ).
Well, this happens. MQL4 evolves and some features we were used to for ages cease to exist, start to suddenly yield inaccurate or indefinite result or change its behaviour ( ol' MQL4-ers still remember the day, when string data type simply ceased to be a string in silence and suddenly started to become a struct. Ok, it was mentioned somewhere deep inside an almost unrelated page of an updated Help-file, yet the code-crashes were painful and long to debug, analyze and re-factor )

How can I reset ESP8266 MicroPython after main.py crashes?

I have a NodeMCU ESP8266 board running MicroPython. I'm running a web server on my ESP8266. This is my first IoT project based on one of these boards.
The below is a snippet of the code.
This is being executed within main.py. Every now and then, something causes the code to crash (perhaps timing and request based). When main.py exits, for whatever reason, I'm dropped back at the python CLI.
I'd like for the board to reset when this happens (if there isn't a better way).
What is the best method of restarting/reseting the ESP8266?
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(5)
print('listening on', addr)
while True:
cl, addr = s.accept()
print('client connected from', addr)
cl_file = cl.makefile('rwb', 0)
print("Request:")
while True:
line = cl_file.readline()
print("Line:" , line)
if not line or line == b'\r\n':
print("breaking")
break
if line == b'GET /active HTTP/1.1\r\n':
MicroPython has machine.reset() function to reset a board.
Python (not just MicroPython) uses exception handling to handle errors.
Combining the two, you can easily achieve what you want. For example:
a = 4
b = 2
try:
a / b
except:
machine.reset()
If in the code above you replace value of b with 0, your board will reset. If you think about it for a bit, you probably will find out that it doesn't make much sense - you don't want your board suddenly reset if you just divide by 0 by mistake or otherwise. There're got to be better ways to handle errors! Likewise, you may want to think about your own case and see if resetting the board is really the best choice. If you think that yes, that's fine, just always keep in mind that you programmed your board to suddenly reset. Otherwise, your next question here may be "My board suddenly resets! Why???" ;-)
It may be late for the original question, but the answer I am going to share might help other people. Consider it is not a final solution, but in many scenarios, it may save a day. You can explore your case.
The solution is using the internal scheduling function of MicroPython. since its execution is guaranteed, then its behavior can be used as a tool to mimic a functional watchdog.
Following code will run with given timers and threshold which can be customized in your case, and if the timer reaches its threshold, and the value of wd_buffer is not updated for that time, then the function might be called, and we repeat the process again.
So in order to prevent the ESP getting restarted in this case after 12 sec, you have to in someplace in your code, periodically (shorter than 12 sec or adjust the timer and threshold according to your need) update the value of the Global wd_buffer variable. Hope it helps.
# Simple WD - Global Variable
wd_feeder = 0
wd_buffer = 0
wd_counter = 0
wd_threshold = 4
def wd_checker(calledvalue):
print('watchdog is checking... feeder= {} buffer= {}'.format(wd_feeder, wd_buffer))
global wd_counter
global wd_buffer
global wd_feeder
if wd_feeder == wd_buffer:
print('state is suspicious ... counter is {} incrementing the counter'.format(wd_counter))
wd_counter += 1
else:
wd_counter = 0
wd_feeder = wd_buffer
if wd_counter == wd_threshold:
print('Counter is reached its threshold, following function will be called')
wd_feeder = wd_buffer = wd_counter = 0
machine.reset()
if __name__ == '__main__':
scheduler_wd = machine.Timer(-1)
scheduler_wd.init(period=3000, mode=machine.Timer.PERIODIC, callback=wd_checker)
you could add a while loop checking for the Flash Button (GPIO pin 0) like this:
import machine
pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
while pin.value():
print('Put your code here...')
print('..this will looping until the Flash button is pressed...')
print('...and then it continues here.')
You could execute your code (which should be outside of the main.py -> other file) from the boot or the main.py. if it drops out it should execute the following code, which could trigger a reset.
You may have to catch the error first.
I hope I helped

readByteSync - is this behavior correct?

stdin.readByteSync has recently been added to Dart.
Using stdin.readByteSync for data entry, I am attempting to allow a default value and if an entry is made by the operator, to clear the default value. If no entry is made and just enter is pressed, then the default is used.
What appears to be happening however is that no terminal output is sent to the terminal until a newline character is entered. Therefore when I do a print() or a stdout.write(), it is delayed until newline is entered.
Therefore, when operator enters first character to override default, the default is not cleared. IE. The default is "abc", data entered is "xx", however "xxc" is showing on screen after entry of "xx". The "problem" appears to be that no "writes" to the terminal are sent until newline is entered.
While I can find an alternative way of doing this, I would like to know if this is the way readByteSync should or must work. If so, I’ll find an alternative way of doing what I want.
// Example program //
import 'dart:io';
void main () {
int iInput;
List<int> lCharCodes = [];
print(""); print("");
String sDefault = "abc";
stdout.write ("Enter data : $sDefault\b\b\b");
while (iInput != 10) { // wait for newline
iInput = stdin.readByteSync();
if (iInput == 8 && lCharCodes.length > 0) { // bs
lCharCodes.removeLast();
} else if (iInput > 31) { // ascii printable char
lCharCodes.add(iInput);
if (lCharCodes.length == 1)
stdout.write (" \b\b\b\b chars cleared"); // clear line
print ("\nlCharCodes length = ${lCharCodes.length}");
}
}
print ("\nData entered = ${new String.fromCharCodes(lCharCodes).trim()}");
}
Results on Command screen are :
c:\Users\Brian\dart-dev1\test\bin>dart testsync001.dart
Enter data : xxc
chars cleared
lCharCodes length = 1
lCharCodes length = 2
Data entered = xx
c:\Users\Brian\dart-dev1\test\bin>
I recently added stdin.readByteSync and readLineSync, to easier create small scrips reading the stdin. However, two things are still missing, for this to be feature-complete.
1) Line mode vs Raw mode. This is basically what you are asking for, a way to get a char as soon as it's printed.
2) Echo on/off. This mode is useful for e.g. typing in passwords, so you can disable the default echo of the characters.
I hope to be able to implement and land these features rather soon.
You can star this bug to track the development of it!
This is common behavior for consoles. Try to flush the output with stdout.flush().
Edit: my mistake. I looked at a very old revision (dartlang-test). The current API does not provide any means to flush stdout. Feel free to file a bug.

Conditional breakpoint that tests multiple stack variables

I'm debugging an application at a point where it uses a dialog box to get some information from the user, and then does some processing on that information. By setting a breakpoint on USER32!CreateDialogParamW I have found the address of its dialog procedure.
At first I just wanted to break when the procedure receives a WM_COMMAND message, so I used the following command: bp 00cfa1c0 "j (dwo(esp+8) == 0x111) ''; 'gc'"
This is unfortunately not enough as the dialog procedure for some reason receives WM_COMMAND messages even when ALT-TABbing between WinDbg and the application. So, now I want it to break when it receives WM_COMMAND with a notification code of BN_CLICKED from the OK button on the dialog. The control ID of the button in the dialog template is 1, and BN_CLICKED is defined as 0 in winuser.h. This means the WPARAM argument of the dialog procedure should be 1 when clicking the OK button.
I tried the following command: bp 00cfa1c0 "j (dwo(esp+8) == 0x111 && dwo(esp+12) == 0x1) ''; 'gc'". This is initially accepted, but when the breakpoint is evaluated it complains: Numeric expression missing from '& dwo(esp+12) == 0x1) ''; 'gc''
Surrounding the 2 expressions with ()'s did not help. I had a look at the help file, but to be honest that confuses me even more. I'm pretty new to WinDbg and English is not my native language. Can someone point me in the right direction?
Thanks in advance.
PS: This is a 32-bit application for which I do not have the source code.
Use a single & - the default syntax for expressions is MASM. && is part of C++ syntax.
The following expressions would work for you:
(dwo(#esp+8) == 0x111 & dwo(#esp+12) == 0x1)
or
##c++(*(int*)(#esp+8) == 0x111 && *(int*)(#esp+12) == 0x1)

Why does my IMessageFilter not always work?

I'm working on Word automation and to get rid of "Call was rejected by callee" / "the message filter indicated that the application is busy" errors I implemented an IMessageFilter. The messagefilter works like a charm when I automate Word directly like:
Word.Documents.Open(...)
Document.SaveAs(...)
But when I call TOleContainer.DoVerb(ovPrimary), I still get errors when Word is displaying a modal dialog. Why does the MessageFilter not work with TOleContainers DoVerb methode?
"Call was rejected by callee" is what you always get when Word is in interactive state, ie displaying a dialog. This is not restricted to Word. It also happens with Excel, for example when the user was editing a cell. And it does not have to be obvious in the user interface either. When you start editing a cell, move focus to another application and come back to Excel, the UI doesn't give you a clue but it is still in "interactive" mode and will reject automation calls with the "Call was rejected by callee" error.
So basically when you automate Word in conjunction with user interaction (and not just with Word in a background process), you should be prepared to get and handle these errors.
Edit
If you want to know whether Excel or Word is in interactive mode before calling any other COM method: just ask the COM-server whether it is "Ready":
Result := _GetActiveOleObject('Excel.Application');
try
aSharedInstance := not VarIsClear(Result);
if aSharedInstance then
Version := Result.Version; // If this produces an exception, then use a dedicated instance.
// In case checking the version does not produce an exception, but Excel still isn't
// ready, we'll check that as well.
// By the way, for some unclear reason, partial evaluation does not work on .Ready,
// so we'll do it like this:
if aSharedInstance and (StrToIntDef(StringBefore('.', Version), 0) >= EXCEL_VERSION_2002) then
aSharedInstance := Result.Ready;
except
aSharedInstance := False;
end;
if not aSharedInstance then
Result := CreateOleObject('Excel.Application');
Update
Apparently Word doesn't have a "Ready" property (whoever said Microsoft was consistent?). In that case you need to determine its readiness yourself by calling a simple (and fast) property before the actual call, and assuming that when that throws an exception, Word isn't ready. In the above example the Version is retrieved before the Ready property. If that throws an exception, we just assume that the application (Excel in this case) isn't ready and proceed accordingly.
Something along the lines of:
while Tries <= MaxTries do
try
Version := Word.Version;
Tries := MaxTries + 1; // Indicate success
Word.TheCallYouReallyWantToDo;
except
Inc(Tries);
sleep(0);
end;
Note Word.Version does not throw an exception when a dialog is open, so that is no use for figuring out whether Word is ready. :( You will have to experiment to find one that does.
IMessageFilter doesn't handle all exceptions, for example, at some points, office applications 'suspend' their object model, at which point it cannot be invoked and throws: 0x800AC472 (VBA_E_IGNORE)
In order to get around this, you have to put your call in a loop and wait for it to succeed:
while(true)
{
try
{
office_app.DoSomething();
break;
}
catch(COMException ce)
{
LOG(ce.Message);
}
}
// continue after successful call
See here for more details.

Resources