Reading statusbar from another application - c++

I'm trying to read the text from another application's statusbar that contains multiple panels. How would I go about that. I have tried to allocate memory in the other application and read that buffer based on this:
http://www.codeproject.com/Articles/5570/Stealing-Program-s-Memory
My current code is:
GetWindowThreadProcessId(grxstatusbar, &statusbarpid);
statusbarprocess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, statusbarpid);
char* _buffer = nullptr;
char buffer[20];
_buffer = (char*)VirtualAllocEx(statusbarprocess, NULL, 20, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(statusbarprocess, _buffer, &buffer, 20, NULL);
SendMessage(grxstatusbar, SB_GETTEXT, (WPARAM)0, (LPARAM)_buffer);
ReadProcessMemory(statusbarprocess, _buffer, buffer, 20, NULL);
VirtualFreeEx(statusbarprocess, _buffer, 0, MEM_RELEASE);
However, buffer is always just gibberish. What would be the best way to approach this problem.

EDIT *****
That won't work if target window is UNICODE. You can use SB_GETTEXTLENGTH to find the text length. Using the UNICODE version:
int char_count;
char_count = SendMessageW(hwndTarget, SB_GETTEXTLENGTH, 1, 0);
if (char_count <= 0)
return 0;
char_count = LOWORD(char_count) + 1;
int datalen = LOWORD(char_count);
datalen *= sizeof(wchar_t);
void* data = VirtualAllocEx(hprocess, NULL, datalen,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
SendMessageW(hwndTarget, SB_GETTEXT, 1, (LPARAM)data);
wchar_t *buf = new wchar_t[char_count];
if (ReadProcessMemory(hprocess, data, buf, datalen, 0))
std::wcout << "buf: " << buf << "\n";
delete[]buf;
VirtualFreeEx(hprocess, data, 0, MEM_RELEASE);
CloseHandle(hprocess);

Related

ReadFileFromDisk kernelmode

I want to read a file from disk using a kernelmode driver. When I try to convert the char buffer to a PCWSTR it either returns "/" or ???????? or some other random characters. I took https://support.microsoft.com/de-at/help/891805/how-to-open-a-file-from-a-kernel-mode-device-driver-and-how-to-read-fr as reference.
I tried the following:
void ZwReadFromFile(PCWSTR FileName, char* outStr)
{
UNICODE_STRING UnicodeName;
OBJECT_ATTRIBUTES ObjectAttribute;
HANDLE FileHandle;
NTSTATUS NTStatus;
IO_STATUS_BLOCK IOStatusBlock;
char FileBuffer[BUFFER_SIZE];
LARGE_INTEGER ByteOffset;
RtlInitUnicodeString(&UnicodeName, FileName);
InitializeObjectAttributes(&ObjectAttribute, &UnicodeName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
NTStatus = ZwCreateFile(&FileHandle,
GENERIC_READ,
&ObjectAttribute, &IOStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);
if (NT_SUCCESS(NTStatus))
{
ByteOffset.LowPart = ByteOffset.HighPart = 0;
NTStatus = ZwReadFile(FileHandle, NULL, NULL, NULL, &IOStatusBlock,
FileBuffer, BUFFER_SIZE, &ByteOffset, NULL);
if (NT_SUCCESS(NTStatus))
{
FileBuffer[BUFFER_SIZE - 1] = '\0';
DbgPrint("%s\n", FileBuffer);
for (int i = 0; i < BUFFER_SIZE; ++i)
{
outStr[i] = FileBuffer[i];
}
}
ZwClose(FileHandle);
}
}
DebugView using DbgPrint("%s\n", buffer); shows the correct output of my textfile, however when I try to convert it like:
char myStr[BUFFER_SIZE];
ZwReadFromFile(L"\\SystemRoot\\test.txt", myStr);
DbgPrint("%s\n", myStr);
It starts to act weird again.
The Reason why I have to convert the char buffer to a PCWSTR is cause I am forced to use: RtlInitUnicodeString(&myUnicode, myStr /*L"TEST"*/);
Im struggling 3 days for it now, did research on google and stackoverflow but nothing really helped me to solve this Issue on my own. I appreciate any help I can get, sorry for my english im not a native speaker.

Write PUNICODE_STRING to file, got garbage data

I'm trying to write two PUNICODE_STRING structure to file, but the data written is invalid, any ideas?
(The data1 is 123 and data2 is 456 in this case)
DWORD dwBytesWritten = 0;
WCHAR buffer[1024];
HANDLE hFile = CreateFile(L"c:\\log.txt", FILE_APPEND_DATA, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
memset(buffer, 0, sizeof(buffer));
wsprintf(buffer, L"%s :: %s\r\n", Data1->Buffer, Data2->Buffer);
WriteFile(hFile, buffer, wcslen(buffer), &dwBytesWritten, NULL);
CloseHandle(hFile);
}
main error is
WriteFile(hFile, buffer, wcslen(buffer), &dwBytesWritten, NULL);
WriteFile always take The number of bytes to be written to the file. but wcslen return the number of characters which in case UINICODE in 2 time less - need * sizeof(WCHAR) or << 1
then for format UNICODE_STRING need use %wZ format - because in general case Buffer can be not 0 terminated. and better use swprintf or _snwprintf instead wsprintf.
at the last always better dynamic allocate needed buffer, then use hardcoded size, which can be overwritten
so i be use next code:
void test(PCUNICODE_STRING Data1, PCUNICODE_STRING Data2)
{
DWORD dwBytesWritten;
PWSTR buffer = (PWSTR)alloca(Data1->Length + Data2->Length + sizeof(L" :: \r\n"));
int n = swprintf(buffer, L"%wZ :: %wZ\r\n", Data1, Data2) * sizeof(WCHAR);
HANDLE hFile = CreateFile(L"c:\\log.txt", FILE_APPEND_DATA, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
WriteFile(hFile, buffer, n, &dwBytesWritten, NULL);
CloseHandle(hFile);
}
}

Windows ListView LVM_GETITEM iImage is always zero

I am trying to do some stuff with the desktop listview. I can get the text of the item with LVM_GETITEM, but the iImage struct member is always zero, and so is the state. I'm running Win 7 64 and compiled for 64 with Dev C++(gcc). I also tried compiling it as 32bit and tested on XP with the same result...just text, image and state are assigned zero. I can also get the item count no problem with ListView_GetItemCount().
HWND progman = FindWindow("progman", NULL);
HWND shell = FindWindowEx(progman, NULL, "shelldll_defview", NULL);
HWND hwndListView = FindWindowEx(shell, NULL, "syslistview32", NULL);
int ct = ListView_GetItemCount(hwndListView);
const DWORD dwBufSize = 1024;
DWORD dwProcessID;
DWORD dwResult;
HANDLE hProcess;
BYTE *lpRemoteBuffer;
LVITEM lvItem = {0};
BYTE lpLocalBuffer[dwBufSize] = {0};
// Get the process id owning the window
::GetWindowThreadProcessId( hwndListView, &dwProcessID );
// Open the process wih all access (You may not have the rights to do this)
hProcess = ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
// Allocate a buffer in the remote process
lpRemoteBuffer = (BYTE*)::VirtualAllocEx( hProcess, NULL, dwBufSize,
MEM_COMMIT, PAGE_READWRITE );
// Fill in the LVITEM struct, this is in your own process
// Set the pszText member to somewhere in the remote buffer,
// For the example I used the address imediately following the LVITEM stuct
lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.cchTextMax = MAX_PATH;
// Point to after LVITEM in the remote buffer
lvItem.pszText = (LPTSTR)(lpRemoteBuffer + sizeof( LVITEM ));
// Copy the local LVITEM to the remote buffer
::WriteProcessMemory( hProcess, (LPVOID)lpRemoteBuffer, &lvItem, sizeof(LVITEM), NULL );
// Send the message
::SendMessage( hwndListView, LVM_GETITEM, 0, (LPARAM)lpRemoteBuffer);
// Read the struct back from the remote process into local buffer
::ReadProcessMemory( hProcess, (LPVOID)lpRemoteBuffer, lpLocalBuffer, dwBufSize, NULL );
//Fix pszText to point to same offset in local buffer
lvItem.pszText = (LPTSTR)(lpLocalBuffer + sizeof( LVITEM ));
MessageBox(hwnd, lvItem.pszText, "", 0);
char txt[10];
ZeroMemory(txt, 10);
MessageBox(hwnd, itoa(lvItem.iImage, txt, 10), "", 0);
MessageBox(hwnd, itoa((int)lvItem.state, txt, 10), "", 0);
// Clean-up
::VirtualFreeEx( hProcess, (LPVOID)lpRemoteBuffer, 0, MEM_RELEASE );
::CloseHandle( hProcess );
You are allocating virtual memory for text. You must also allocate virtual memory for LVITEM. Then assign the text memory to lvItem.pszText, and then read both memory. It has to be compiled 64-bit for 64-bit systems. Add more error checks.
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ |
PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);
const DWORD dwBufSize = 1024;
void* pbuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
void* pitem = VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
LVITEM lvItem = { 0 };
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.cchTextMax = MAX_PATH;
lvItem.pszText = (char*)pbuf;
WriteProcessMemory(hProcess, pitem, &lvItem, sizeof(LVITEM), NULL);
if (SendMessage(hwndListView, LVM_GETITEM, 0, (LPARAM)(LVITEM*)(pitem)))
{
char buf[dwBufSize];
if (ReadProcessMemory(hProcess, pbuf, buf, dwBufSize, 0))
{
OutputDebugString(buf);
OutputDebugString(", ");
if (ReadProcessMemory(hProcess, pitem, &lvItem, sizeof(LVITEM), 0))
{
_itoa_s(lvItem.iImage, buf, 10);
OutputDebugString(buf);
OutputDebugString("\n");
}
}
}
VirtualFreeEx(hProcess, pitem, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pbuf, 0, MEM_RELEASE);
CloseHandle(hProcess);

write file in raw usb c++

this is my code:
int main(int argc, CHAR* argv[]) {
using namespace std;
PVOID data[1024];
DWORD dwBytesRead = 0;
DWORD dwBytesWrite = 512;
HANDLE hFile = CreateFile(L"\\\\.\\E:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open usb
if (hFile == INVALID_HANDLE_VALUE) {
printf("Error %x", GetLastError());
return 1;
}
printf ("created usb hendle\n");
LARGE_INTEGER a = { 50688 };
SetFilePointerEx(hFile, a,NULL,0); //set the pointer to c600
printf("got usb pointer set\n");
PVOID ToBe = ":) hello this is our file -> ";
if (WriteFile(hFile,ToBe,512 ,&dwBytesWrite, NULL) == 0)
{
printf("writeFile error: %x", GetLastError());
CloseHandle(hFile);
return 1;
}
printf("write the first string in isb\n");
HANDLE aFile = CreateFile(L"C:\\Users\\h7080y_dxlq\\Downloads\\Video\\88250.mp4", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); //open the file handle
printf("created mp4 hendle\n");
if (aFile == INVALID_HANDLE_VALUE) {
printf("Error %x", GetLastError());
return 1;
}
if (ReadFile(aFile, &data, 512, &dwBytesRead, NULL) == 0) {
printf("ReadFile error: %x", GetLastError());
return 1;
}
DWORD dwPos;
printf("checked for read errors in mp4 passed o.k.\n");
while (ReadFile(aFile, data,512, &dwBytesRead, NULL) && dwBytesRead > 0) //read file
{
dwPos = SetFilePointerEx(hFile, a, NULL, 0);
LockFile(hFile, dwPos, 0, dwBytesRead, 0);
WriteFile(hFile, data, 512, &dwBytesWrite, NULL); // write 512 bit chunk at the time to usb
UnlockFile(hFile, dwPos, 0, dwBytesRead, 0);
a = { 50688+512 }; // promot
}
printf("write all mp4 to the usb directtly\n");
ToBe = "<- this is the end of file , see you soon :)";
if (WriteFile(hFile, ToBe, 512, &dwBytesWrite, NULL) == 0)
{
printf("writeFile error: %x", GetLastError());
CloseHandle(hFile);
return 1;
}
printf("after end massage \n");
CloseHandle(hFile);
system("pause");
return 0;
}
I try to take a file (mp4 in this case) , and read it chunk by chunk (512 bit at the time) , take the chunk and write it to usb and so on till end of file .
Now, the problem is:
A the loop never ends.
B that it don't write the file to the USB, it looks like its write on the same spot again and again...
How can I fix it?
LARGE_INTEGER a = { 50688 };
while (ReadFile(aFile, data,512, &dwBytesRead, NULL) && dwBytesRead > 0)
{
dwPos = SetFilePointerEx(hFile, a, NULL, 0);
LockFile(hFile, dwPos, 0, dwBytesRead, 0);
WriteFile(hFile, data, 512, &dwBytesWrite, NULL);
UnlockFile(hFile, dwPos, 0, dwBytesRead, 0);
a = { 50688+512 };
}
The first time round the loop you set the file pointer to 50688 and write there. Each subsequent time round the loop you set the file pointer to 50688+512 and write there.
It looks like it writes to the same spot again and again.
Yes indeed. That's exactly what your code specifies. Your should set the file pointer on aFile outside the loop, and let it advance naturally as the file is written. Something like this:
dwPos = 50688;
LARGE_INTEGER a = { dwPos };
if (!SetFilePointerEx(hFile, a, NULL, 0))
{
// handle error
}
while (ReadFile(aFile, data, 512, &dwBytesRead, NULL) && dwBytesRead > 0)
{
LockFile(hFile, dwPos, 0, dwBytesRead, 0);
WriteFile(hFile, data, 512, &dwBytesWrite, NULL);
UnlockFile(hFile, dwPos, 0, dwBytesRead, 0);
dwPos += 512;
}
Note that your calls to LockFile, and the use of a DWORD for dwPos, means that you cannot write a file larger than 4GB.
It is also far from clear to me that the calls to LockFile are needed. Since your original code got the handling of dwPos wrong, it's clear that you weren't locking the parts of the file you intended to. It is my belief that you should simply remove them. In which case the code will become:
LARGE_INTEGER a = { 50688 };
if (!SetFilePointerEx(hFile, a, NULL, 0))
{
// handle error
}
while (ReadFile(aFile, data, 512, &dwBytesRead, NULL) && dwBytesRead > 0)
{
if (!WriteFile(hFile, data, 512, &dwBytesWrite, NULL))
{
// handle error
}
}
You have also omitted large amounts of error checking in this code. I would not be surprised to find that there are a number of other problems with it. I don't particularly want to try to find every single error in your code, and hope that what I have written is enough to help you on your way.

MFC read file and display it as HEX (hexdump)

I need to read binary file and display bytes at certain offset so i can change that bytes and then save an updated file. I don't really understand how can i achieve that. I'm using MFC/VS 2008
So, i'am opening file using WinApi and getting its content to BYTE buffer. But i'm not sure how to print data at certain offset to (for example) an editbox and the main quesiton - how to edit this data (like in HEX editor) and save updated file.
CFileDialog FileDlg(TRUE, "*", "*", OFN_FILEMUSTEXIST);
if(FileDlg.DoModal() == IDOK)
{
CString pathName = FileDlg.GetPathName();
//MessageBox(pathName, NULL, MB_OK);
// Implement opening and reading file in here.
//Change the window's title to the opened file's title.
//CString fileName = FileDlg.GetFileTitle();
//SetWindowText(fileName);
HANDLE hFile = CreateFile(pathName.GetString(), GENERIC_READ | GENERIC_WRITE, NULL,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if(!hFile)
return;
DWORD dwSize = GetFileSize(hFile, NULL);
BYTE *Content = (BYTE *)malloc(dwSize);
DWORD dwRead;
if(!ReadFile(hFile, Content, dwSize, &dwRead, NULL))
return;
}
Here is a solution with owner draw ListBox (size=fixed-sized, sort=false)
class CListHex : public CListBox
{
public:
std::vector<BYTE> Buffer;
CRect SaveItemRect;
CEdit Edit;
int Index;
void setup()
{
if (Edit.m_hWnd && IsWindow(Edit.m_hWnd))
return;
Edit.Create(WS_CHILD | WS_BORDER | ES_CENTER, CRect(0, 0, 0, 0), this, 1);
Edit.SetFont(GetFont());
Edit.SetLimitText(2);
SetItemHeight(0, 21);
}
void read()
{
HANDLE hfile = CreateFile(L"in.txt", GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
{
DWORD size = GetFileSize(hfile, NULL);
Buffer.resize(size);
ReadFile(hfile, &Buffer[0], size, 0, NULL);
CloseHandle(hfile);
for (int i = 0; i <= (int)Buffer.size() / 16; i++)
AddString(0);
}
else
{
MessageBox(L"error");
}
}
void write()
{
HANDLE hFile = CreateFile(L"out.txt", GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
{
WriteFile(hFile, &Buffer[0], Buffer.size(), 0, 0);
CloseHandle(hFile);
}
else
{
MessageBox(L"error");
}
}
void DrawItem(LPDRAWITEMSTRUCT di)
{
SaveItemRect = di->rcItem;
CRect r = di->rcItem;
r.right = r.left + r.Width() / 16;
HBRUSH brush = (HBRUSH)SelectObject(di->hDC, GetStockObject(WHITE_BRUSH));
FillRect(di->hDC, &di->rcItem, brush);
for (int i = 0; i < 16; i++)
{
unsigned int cursor = di->itemID * 16 + i;
if (cursor >= Buffer.size())
break;
CString s;
s.Format(L"%02X", Buffer[cursor]);
DrawText(di->hDC, s, s.GetLength(), r, DT_EDITCONTROL|DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
}
void OnLButtonDown(UINT f, CPoint p)
{
CListBox::OnLButtonDown(f, p);
setup();
int w = SaveItemRect.Width() / 16;
CRect r = SaveItemRect;
r.right = r.left + w;
for (int i = 0; i < 16; i++)
{
if (r.PtInRect(p))
{
unsigned int index = GetCurSel() * 16 + i;
if (index >= Buffer.size())
return;
Index = index;
GetParent()->SetRedraw(0);
CString s;
s.Format(L"%02X", Buffer[Index]);
Edit.SetWindowText(s);
Edit.SetWindowPos(0, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER | SWP_NOREDRAW | SWP_SHOWWINDOW);
Edit.SetFocus();
GetParent()->SetRedraw(1);
break;
}
r.OffsetRect(w, 0);
}
}
//******CHANGED******
void MeasureItem(LPMEASUREITEMSTRUCT m) { m->itemHeight=21; }
int CompareItem(LPCOMPAREITEMSTRUCT) { return 0; }
//******CHANGED******
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CListHex, CListBox)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
In addition,
You can add subclass for CEdit
Override CMyEdit::OnKillFocus() to close the edit box
Override CMyEdit::OnChar to accept hexadecimal characters only
Read Edit string then convert to unsigned char and assign it to Buffer[Index].
Override CListHex::OnVScroll to close the edit box
//CHANGED:
To create the function try to do it manually, to make sure it get the right flags:
list.Create(WS_VSCROLL | WS_BORDER | WS_CHILD | WS_VISIBLE | LBS_USETABSTOPS | LBS_OWNERDRAWFIXED , CRect(10, 10, 450, 350), this, 1001);
list.read();