Re: Some Reminders
Posted: Sat Aug 01, 2015 2:52 pm
Thanks. I just pushed changes for those two.
Code: Select all
static std::string buffer = psettings->getString(CONFVAR_LOG_DIRECTORY);
static const char *logDir = buffer.c_str();
This is out of openLog(which makes trouble since forever) there is a second line in the main.cpp where it is the same(take a look in the download or the repo), c_str() itself isn't the problem it is you so that when an object is only on the right side in this case string it will be there only for a very little time, at least this is was I get out of the link I posted and basically when I make a var which contain it from a return value a real copy will be made of the object.Administrator wrote:c_str() returns a const char *. It should be valid until the base string is modified or goes out of scope. At worst, you would have an invalid pointer, but it should never be changed to NULL. What file & line is that call on, and at what point did you get an error about a NULL pointer?
Code: Select all
int Process_lua::readBatch(lua_State *L)
{
if( lua_gettop(L) != 3 )
wrongArgs(L);
checkType(L, LT_USERDATA, 1);
checkType(L, LT_NUMBER, 2);
checkType(L, LT_STRING, 3);
ProcHandle *pHandle = static_cast<ProcHandle *>(lua_touserdata(L, 1));
size_t address = (size_t)lua_tointeger(L, 2);
const char *fmt = lua_tostring(L, 3);
std::vector<BatchJob> jobs;
size_t readLen = readBatch_parsefmt(fmt, jobs);
char *readBuffer = 0;
try {
readBuffer = new char[readLen+1];
} catch( std::bad_alloc &ba ) { badAllocation(); }
SIZE_T bytesRead = 0;
int success = ReadProcessMemory(pHandle->handle, (LPVOID)address, (void *)readBuffer, readLen, &bytesRead);
if( !success || bytesRead != readLen )
{ // Throw error
delete []readBuffer;
int errCode = GetLastError();
pushLuaErrorEvent(L, "Failure reading memory from 0x%p at 0x%p. "\
"Error code %i (%s)",
pHandle->handle, address, errCode, getWindowsErrorString(errCode).c_str());
return 0;
}
Code: Select all
template <class T>
static T readMemory(HANDLE process, size_t address, int &err)
{
T buffer;
SIZE_T bytesread = 0;
err = 0;
int success = 0;
success = ReadProcessMemory(process, (LPCVOID)address,
(void *)&buffer, sizeof(T), &bytesread);
if( success == 0 ){
int trys_counter = 0;
NtSuspendProcess pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess");
NtResumeProcess pfnNtResumeProcess = (NtResumeProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtResumeProcess");
while(success == 0 && trys_counter < 50){
pfnNtSuspendProcess(process);
success = ReadProcessMemory(process, (LPCVOID)address,
(void *)&buffer, sizeof(T), &bytesread);
pfnNtResumeProcess(process);
// if it still fail the only reason could be we looked it in a state where it access itself the memory
// so give it sometime and try again
if( success == 0 )
Sleep(5);
trys_counter ++;
}
}
if( success == 0 )
err = MEMORY_READ_FAIL;
return buffer;
}
template <class T>
static void writeMemory(HANDLE process, size_t address, T data, int &err)
{
SIZE_T byteswritten = 0;
err = 0;
int success = 0;
DWORD old;
VirtualProtectEx(process, (void *)address, sizeof(T), PAGE_READWRITE, &old);
success = WriteProcessMemory(process, (void *)address,
(void*)&data, sizeof(T), &byteswritten);
VirtualProtectEx(process, (void *)address, sizeof(T), old, &old);
if( success == 0 ){
int trys_counter = 0;
NtSuspendProcess pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess");
NtResumeProcess pfnNtResumeProcess = (NtResumeProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtResumeProcess");
while(success == 0 && trys_counter < 50){
pfnNtSuspendProcess(process);
VirtualProtectEx(process, (void *)address, sizeof(T), PAGE_READWRITE, &old);
success = WriteProcessMemory(process, (void *)address,
(void*)&data, sizeof(T), &byteswritten);
VirtualProtectEx(process, (void *)address, sizeof(T), old, &old);
// if it still fail the only reason could be we looked it in a state where it access itself the memory
// so give it sometime and try again
pfnNtResumeProcess(process);
if( success == 0 )
Sleep(5);
trys_counter ++;
}
if( success == 0 )
err = MEMORY_WRITE_FAIL;
}
}
Code: Select all
std::string fullcmd;
std::string result;
std::string ex = "\"";
std::cin.clear();
getline(std::cin, fullcmd);
std::cin.clear();
if (fullcmd == "") {
result = scriptGUIDialog(previousScript);
fullcmd = ex + result + ex;
}
//previousScript = fullcmd; // Remember this.
return fullcmd;
}
Another good catch. Fixed that up.that return statement is missing without it a memory violation is possible.
Hmm... I'm a bit torn on this one. I'm not sure that freezing the application for 3-400ms will help with memory reading, but it can definitely make things a bit of a mess for the user. It is definitely an interesting idea though. Go ahead and give it a shot and see what happens. Report back with your results. I think if I include it, it will be togglable in the config.The other thing is hm I'm still not sure if it is necessary but I think the way MM2 reading and writing memory isn't so different from MM1:
so my idea would be ?!:
Wouldn't surprise me if there was a bug as I'm using a bit of a hack to get around using complex regex, but it seems to be working fine for me.Okay I found something different I'm not 100% sure but splitArgs don't work as intended or it was forgotten.
Code: Select all
Script> "test scripts/args" abc "def 123"
Running './scripts/test scripts/args.lua'
Args:
1 ./scripts/test scripts/args.lua
2 abc
3 def 123
CWD: D:/sync/micromacro/scripts/test scripts
I just finished recompiling MM2 new XDI rewrote a bunch of path code, so go ahead and check out that commit here: https://github.com/elverion/micromacro/ ... fc8b623919
That should resolve your issue with openLog() (although I'm unable to reproduce it) as well as make the code cleaner and more robust.