I've written a simple MIDI console application in C++. Here's the whole thing:
#include <windows.h>
#include <iostream>
#include <math.h>
using namespace std;
void CALLBACK midiInputCallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
switch (wMsg) {
case MIM_MOREDATA:
case MIM_DATA:
cout << dwParam1 << " ";
PlaySound("jingle.wav", NULL, SND_ASYNC | SND_FILENAME);
break;
}
}
int main() {
unsigned int numDevs = midiInGetNumDevs();
cout << numDevs << " MIDI devices connected:" << endl;
MIDIINCAPS inputCapabilities;
for (unsigned int i = 0; i < numDevs; i++) {
midiInGetDevCaps(i, &inputCapabilities, sizeof(inputCapabilities));
cout << "[" << i << "] " << inputCapabilities.szPname << endl;
}
int portID;
cout << "Enter the port which you want to connect to: ";
cin >> portID;
cout << "Trying to connect with the device on port " << portID << "..." << endl;
LPHMIDIIN device = new HMIDIIN[numDevs];
int flag = midiInOpen(&device[portID], portID, (DWORD)&midiInputCallback, 0, CALLBACK_FUNCTION);
if (flag != MMSYSERR_NOERROR) {
cout << "Error opening MIDI port." << endl;
return 1;
} else {
cout << "You are now connected to port " << portID << "!" << endl;
midiInStart(device[portID]);
}
while (1) {}
}
You can see that there's a callback function for handling the incoming MIDI messages from the device. Here is the description of this function on MSDN. On that page they say that the meaning of dwParam1 and dwParam2 are specified to the messagetype (wMsg), like MIM_DATA.
If I look up the documentation of MIM_DATA, I can see that it is a doubleword (DWORD?) and that it has a 'high word' and a 'low word'. How can I now get data like the name of the control on the MIDI device that sended the data and what value it sends?
I would appreciate it if somebody can correct my code if it can be done better.
Thanks :)
To access the data you need to use dwParam1 and dwParam2 and call the macros HIWORD and LOWORD to get the high and low word from them. Respectively use HIBYTE and LOBYTE to get the data out of those words. In case of MIM_DATA, unfortunately that's byte encoded MIDI data, so you'll have to find the specific meanings for those -- these are documented here -- MIDI Messages.
Your code however has a potential problem -- as we read in the MSDN pages:
"Applications should not call any
multimedia functions from inside the
callback function, as doing so can
cause a deadlock. Other system
functions can safely be called from
the callback".
And you're calling PlaySound in the Callback...
Related
I am trying to change the value of minerals in Starcraft II to learn win32.
I am not into gaming at all. but chose my childhood game to leearn win32 and operating systems.
Here is my code.
everything works, I can get the handle and its process id.
however reading the value does not work.
From cheat engine, I can change the value of minerals to whatever I like.
Here is the memory address of the minerals.
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
int newMineral = 2000;
int readMineral = 0;
HWND hwnd = FindWindowA(NULL, "Brood War");
if (hwnd == NULL)
{
cout << "Cannot find window." << endl;
Sleep(30000);
exit(-1);
}
else
{
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
if (procID == NULL)
{
cout << "Cannot find procssID." << endl;
Sleep(30000);
exit(-1);
}
else
{
cout << "process exists." << endl;
cout << procID << endl;
//WriteProcessMemory(handle, (LPVOID)0x57F0F0, &newMineral, sizeof(newMineral), 0);
ReadProcessMemory(handle, (PBYTE*)0x57F0F0, &readMineral, sizeof(int), 0);
cout << readMineral << endl;
}
}
return 0;
I think it is the format of my memory address maybe since the handle and processID are obtainable.
i'm trying to make a little program to my university that can change values in the memory of another process. With the exact address value that the Cheat Engine give me i can do this, but not ever the value is the same then my problem is with the memory pointers. In the following image i has the every offset that i found in the pointer scan map:
I already make a program but it not work and ever gives me 299 error code, i Run it as administrator. The code is the following:
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <queue>
using namespace std;
int main() {
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
// Snapshot to list all process
HANDLE pHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (pHandlers == NULL) {
cout << "Error 1";
return 1;
}
// Listing process
if (Process32First(pHandlers, &pEntry)) {
while (Process32Next(pHandlers, &pEntry)) {
// Convert value to string
wstring wstr(pEntry.szExeFile);
string str(wstr.begin(), wstr.end());
// Check if is the process that i wan't
if (str == "Playgroundd.exe") {
MODULEENTRY32 mEntry;
mEntry.dwSize = sizeof(MODULEENTRY32);
// Snapshot to list all modules inside process
HANDLE mHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pEntry.th32ProcessID);
if (mHandlers == NULL) {
cout << "Error 2";
return 1;
}
// Usually the first process is the main module
if (Module32First(mHandlers, &mEntry)) {
// Convert the name to string
wstring wstrr(mEntry.szExePath);
string strr(wstrr.begin(), wstrr.end());
if (strr.find("Playgroundd.exe")) {
// Get the base address of module
DWORD moduleBaseAddress = (DWORD)mEntry.modBaseAddr;
// Append initial value
moduleBaseAddress += (DWORD)0x000000E8;
// Offsets defined
DWORD offsets[] = {0x88,0x98,0x90,0x20,0x10,0x48,0x904};
// Open process with the right process id
cout << "process id: " << pEntry.th32ProcessID << endl << endl;
HANDLE processHandler = OpenProcess(PROCESS_ALL_ACCESS, 0, pEntry.th32ProcessID);
if (processHandler == NULL) {
cout << "Can't open the process";
return 1;
}
// Sum offsets
for (int i = 0; i < 7;i++) {
moduleBaseAddress += offsets[i];
}
int receive = 0;
size_t bytesRead = 0;
bool resultStatus = ReadProcessMemory(processHandler,
(LPCVOID)moduleBaseAddress, &receive, sizeof(receive), &bytesRead);
cout << "result status :" << resultStatus << endl;
cout << "Received : " << receive << endl;
cout << "Bytes read : " << bytesRead << endl;
cout << "Possible error code : " << GetLastError() << endl;
}
else {
cout << "Can't find module";
return 1;
}
}
}
}
}
};
This is the output of the above program, the error code can be ignored if the result status be non-zero
result status :0
Received : 0
Bytes read : 0
Possible error code : 299
What i am doing wrong?
As pointed by the comment above, your calculation of the target address is questionable.
Your use of GetLastError is unsafe - you should call it immediately after FAILED call to ReadProcessMemory. However, in this case, cout << ... doesn't change that code, so you are OK.
According to docs
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
And this post states
ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault.
I have been experimenting with various aspects of the Windows API and thought I would give process memory manipulation a try. Previously I had been trying to do this in native C++ using this method: C++ - Get value of a particular memory address
However, this method does not work and I found a response somewhere on the Cplusplus forum that told me to use ReadProcessMemory. I found that WriteProcessMemory works just fine when attempting to edit values, but ReadProcessMemory either fails (returning error code 299) or crashes the application.
Here is my code:
#include <iostream>
#include <cstdint>
#include <Windows.h>
#include <cstdio>
using namespace std;
int main()
{
LPVOID bytes;
DWORD pid;
SIZE_T *num_bytes_read;
int temp;
SIZE_T size = sizeof(temp);
LPCVOID address = reinterpret_cast<int*>(0x404004);
HWND hwnd = FindWindow(NULL, "C:\\Users\\Delkarix\\Desktop\\memory_edit_test.exe");
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
BOOL worked = ReadProcessMemory(hProcess, address, bytes, size, num_bytes_read);
cout << "ERROR: " << GetLastError() << endl;
cout << "PROCESS: " << hProcess << endl;
cout << "BYTES: " << bytes << endl;
cout << "BASE ADDRESS: " << address << endl;
cout << "FUNCTION SUCCESS: " << worked << endl;
cout << "BYTES READ: " << *num_bytes_read << endl;
CloseHandle(hProcess);
}
I have noticed that the application crashes when the num_bytes_read variable is a pointer (the 5th parameter of ReadProcessMemory is the num_bytes_read variable) and it throws error 299 when it is not a pointer (the 5th parameter of ReadProcessMemory is the pointer to the num_bytes_read variable).
Here is the code for the memory_edit_test.cpp:
#include <iostream>
using namespace std;
int test = 6;
int main() {
string input;
cout << &test << endl; // Where I got the address 0x404004
getline(cin, input);
cout << test << endl; // Used to check the value against the one I got from ReadProcessMemory
getline(cin, input);
}
How can I get ReadProcessMemory to succeed? Answers to similar questions on StackOverflow either do nothing or they just make the problem worse.
The problem is very simple, third parameter to ReadProcessMemory is meant to point to a buffer, where the memory read will be written to. You just give it an unintialised pointer. Similar problem with the fifth parameter as well.
Your code should look something like this
int temp;
SIZE_T num_bytes_read;
BOOL worked = ReadProcessMemory(hProcess, address, &temp, sizeof temp, &num_bytes_read);
Note third and fifth parameters are pointers to already existing memory. Declare a variable and use & to get its address.
In efforts to learn more C++, I have chosen - you know - something fun to do and that is writing to random application's memory. The code I have written seems to work on all applications but I am having difficulties getting it to work with Google Chrome tabs.
What I am trying to do is simply change my score on Slope (on y8.com) for which I have the memory address with the help of cheat engine. The problem seems to be retrieving the Process ID of the tab. Using Chrome's Task Manager, I translated the tab's address to hex, opened the process in cheat engine and found the score address.
Here the problem comes. Whenever I use GetWindowThreadProcessId(window, &processID); cout << processID, it doesn't print the ID which can be seen in chrome's task manager for the game's tab. In fact, it prints the ID of chrome as a whole (which I know because in chrome's task manager, "chrome" has that ID). And the score cannot be written to or read from chrome's processID. If I ignore this problem, buffer seems to always print as 0.. no changes.
I am very new to this, and expect myself not to know what I am talking about. If you test the game yourself, you'll have to find the address that your chrome is using at the time. But here's the code (I have commented out the WriteProcessMemory and put Read just so I get it working before I write anything):
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main() {
int buffer = 0;
LPVOID address = (LPVOID)0x15E7E1B0FB8/*(0x000000000192DFA0 + 0x0000291D8FE04000 + 0x18)*/;
cout << "Begin playing the game and wait for the 0 score to appear" << endl;
HWND window = FindWindow(NULL, "Slope Game - Play online at Y8.com");
if (window) {
cout << "Game found running! You ready to hax?" << endl;
DWORD processID = 11180;
GetWindowThreadProcessId(window, &processID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
if (handle) {
/*string hackedScoreInput = "0";
cout << "Desired Score: " << flush; getline(cin, hackedScoreInput);
int hackedScore = stoi(hackedScoreInput);
int suc = WriteProcessMemory(handle, address, &hackedScore, sizeof(hackedScore), NULL);
if (suc > 0) {
cout << "HAXED!" << endl;
CloseHandle(handle);
}
else {
cerr << GetLastError() << endl;
cerr << hackedScore << " of size: " << sizeof(hackedScore) << endl;
return 3;
}*/
while (true) {
ReadProcessMemory(handle, address, &buffer, sizeof(buffer), NULL);
cout << buffer << " at adress: " << processID << endl;
Sleep(100);
system("CLS");
}
}
else {
cerr << "Could not open the process" << endl;
return 2;
}
}
else {
cerr << "Error! Could not find window!" << endl;
Sleep(3000);
return 1;
}
return 0;
}
What's wrong with the code?
Modern browsers use multiple processes and there is no rule that says that a browser tab HWND has to be owned by the process where the web page "runs".
Some browser implementations might have one main process that hosts the UI including all tabs but the actual web page content might be rendered to a shared bitmap/memory in a different process where it is safe to run scripts etc.
Chrome is open source so you could take a look and see if there is a way to find out which render process renders a certain tab by looking at the child processes command line arguments.
I am writing a simple user interface to communicate with an In-Circuit Serial Programmer. The intention is to remove the need for the end-user to type over a dozen cryptic commands via PuTTY, and in fact to remove the need for typing altogether as the user is inevitably wearing keyboard-unfriendly gloves. The process requires interaction with the user, so a simple batch script is not feasible.
I can find the correct COM port and successfully open it. I can send data, but the response is only ever the equivalent of "unknown command".
I shall refrain from posting the whole code as nobody will be able to recreate my circumstances. However, I can always add everything if necessary.
I open comms using CreateFile() and use WriteFile() or ReadFile() to communicate. For example:
if (!WriteFile(hSerial, "r rc.all\r\n", 10, &bytesRead, NULL))
cout << "Error sending message (" << GetLastError() << ")" << endl;
if (!ReadFile(hSerial, msgBuffer, 15, &bytesRead, NULL))
cout << "No message received" << endl
else
{
cout << "Bytes rcvd = " << bytesRead << endl;
for (int x=0; x<bytesRead; x++)
cout << (unsigned int) msgBuffer[x] << " ";
}
No matter what message I send (either "r rc.all" or "foobar") I always get the same response:
Bytes rcvd = 3
62 13 10
Which is >\r\n. I have tried slowing down the sending of characters to simulate them being typed, but this invokes the same response from the ICSP:
bool serialSend(LPCSTR MESSAGE, PHANDLE hSERIAL)
{
DWORD bytesWritten;
char writeBuff[2];
writeBuff[1] = '\0';
for (UINT x = 0; x <= strnlen(MESSAGE, 64); x++)
{
cout << MESSAGE[x];
writeBuff[0] = MESSAGE[x];
if (!WriteFile(*hSERIAL, writeBuff, 1, &bytesWritten, NULL))
cout << "\t\tERROR! (character '" << MESSAGE[x] << "', error " << GetLastError() << ")" << endl;
Sleep(100);
}
writeBuff[0] = '\n';
if (!WriteFile(*hSERIAL, writeBuff, 1, &bytesWritten, NULL))
cout << "\t\tERROR! (character 'LF', error " << GetLastError() << ")" << endl;
Sleep(100);
writeBuff[0] = '\r';
if (!WriteFile(*hSERIAL, writeBuff, 1, &bytesWritten, NULL))
cout << "\t\tERROR! (character 'CR', error " << GetLastError() << ")" << endl;
cout << endl;
return true;
}
I have set the parameters of the serial connection to match the settings in PuTTY - Byte length, stop bit, parity, flow control, etc. The fact that I get a response at all suggests the connections is not at fault.
What is wrong?
The problem turned out to be the \r\n combination sent at the end of the message.
Sending just \r or just \n does not work. However, sending (char) 13 does - even though that should be the same as \r.
There also needs to be a pause between the sending of each character; 1ms is sufficient.