Find command line of program with PEB? - windows

I need find the command line of program with PEB.
I use FS:[0x30] to find PEB
int wmain(int argc, WCHAR *argv[])
{
PVOID pebAddress =( void * ) __readfsdword( 0x30 ); /* get the PEB address */
PVOID rtlUserProcParamsAddress;
ReadProcessMemory(GetCurrentProcess(),(PCHAR)pebAddress+ 0x10,
&rtlUserProcParamsAddress, /* we'll just read directly into our variable */
sizeof(PVOID),
NULL
);
UNICODE_STRING commandLine;
ReadProcessMemory(GetCurrentProcess(), (PCHAR)rtlUserProcParamsAddress + 0x40,&commandLine, sizeof(commandLine), NULL);
WCHAR * commandLineContents;
commandLineContents = (WCHAR *)malloc(commandLine.Length);
ReadProcessMemory(GetCurrentProcess(), commandLine.Buffer,commandLineContents, commandLine.Length, NULL);
printf("%.*S\n", commandLine.Length / 2, commandLineContents);
}
but it does not work. I need use only PEB not GetCommandLine(void);

Works fine for me on Windows 7 with VC2010. printf might be defined as wprintf which treats %S as ANSI string. It's a long shot as that would also cause it to complain about the format string being non-Unicode. Try outputting the string using MessageBoxW to be sure you're treating everything as Unicode.
BTW, you don't need to use ReadProcessMemory when you're reading from your own process.

Why would you need to use the PEB? Have you looked at the contents of argv at all?
And what's the (to me) scary looking commandLine.Length / 2 for in your code...?

Related

copy_from_user is fetching unexpected data

I want to use the write sycall for copying a struct
from userspace to kernel.
In both user and kernel space, the struct is defined as
struct packet{
unsigned char packet[256];
int length;
}__attribute__ ((packed));
User space uses a local variable of type struct packet and passes it to the write syscall.
struct packet p;
/* ... (fill in data) */
printf("packet.length: %d\n",packet.length); /* looks correct */
result = write(uartFD, &p, sizeof(struct packet));
The kernel side looks like this, checking for correct length is done, just removed from example.
/* write syscall */
ssize_t packet_write(
struct file *file_ptr,
const char __user *user_buffer,
size_t count, loff_t *position)
{
struct packet p;
int retval;
if (copy_from_user((void*)&p, user_buffer, sizeof(struct packet))){
retval = -EACCES;
goto err;
}
/* looks wrong - different numbers like 96373062 or 96373958 */
printk("packet length: %d\n",p.length);
The opposite direction using read sycall is working as expected:
/* read syscall */
struct packet p;
/* ... (fill in data) */
copy_to_user(user_buffer, (void*)&p, sizeof(struct packet));
/* userspace */
read(uartFD, (void*)&packet, sizeof(struct packet));
What am I doing wrong with write syscall?
(Posted on behalf of the OP).
This is solved - it was my own silly. Both copying an integer and an unsigned char buffer separately was working, so it had to be something about the struct.
One site was packed, the other was not... reusing old code...

Find out the process name by pid in osx kernel extension

I am working on kernel extension and want to find out how to find process name by pid in kernel extension
This code works great in user space
static char procdata[4096];
int mib[3] = { CTL_KERN, KERN_PROCARGS, pid };
procdata[0] = '\0'; // clear
size_t size = sizeof(procdata);
if (sysctl(mib, 3, procdata, &size, NULL, 0)) {
return ERROR(ERROR_INTERNAL);
}
procdata[sizeof(procdata)-2] = ':';
procdata[sizeof(procdata)-1] = '\0';
ret = procdata;
return SUCCESS;
but for the kernel space, there are errors such as "Use of undeclared identifier 'CTL_KERN'" (even if I add #include )
What is the correct way to do it in kernel extension?
The Kernel.framework header <sys/proc.h> is what you're looking for.
In particular, you can use proc_name() to get a process's name given its PID:
/* this routine copies the process's name of the executable to the passed in buffer. It
* is always null terminated. The size of the buffer is to be passed in as well. This
* routine is to be used typically for debugging
*/
void proc_name(int pid, char * buf, int size);
Note however, that the name will be truncated to MAXCOMLEN - 16 bytes.
You might also be able to use the sysctl via sysctlbyname() from the kernel. In my experience, that function doesn't work well though, as the sysctl buffer memory handling isn't expecting buffers in kernel address space, so most types of sysctl will cause a kernel panic if called from a non-kernel thread. It also doesn't seem to work for all sysctls.

UNICODE_STRING to std String Conversion

I am using pFileObject->FileName to get the name of file opened in a kernel mode filter driver.This file name returned by this is in the form of UNICODE_STRING. I want to convert it into std String. What is the method ??? Please do provide example if possible...
Below is the code
NTSTATUS FsFilterDispatchCreate(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
DbgPrint("%wZ\n", &pFileObject->FileName);
return FsFilterDispatchPassThrough(DeviceObject, Irp);
}
I agree with Hans' comment. Making std:: classes work in Windows kernel mode is extremely difficult if not impossible. The default WinDDK environment is C rather than C++. Your best bet is to convert UNICODE_STRING to ANSI null-terminated string. (You can print it with DbgPrint("%s"...) etc). See example below.
UNICODE_STRING tmp;
// ...
ANSI_STRING dest;
ULONG unicodeBufferSize = tmp.Length;
// Length of unicode string in bytes must be enough to keep ANSI string
dest.Buffer = (PCHAR)ExAllocatePool(NonPagedPool, unicodeBufferSize+1);
// check for allocation failure...
dest.Length = 0;
dest.MaximumLength = unicodeBufferSize+1;
RtlUnicodeStringToAnsiString(&dest, &tmp, FALSE);
// check for failure...
dest.Buffer[dest.Length] = 0; // now we get it in dest.Buffer

RegEnumKeyEx doesn't change file name Qt

I'm a very new to winapi and having a lot of troubles
Trying to extract all connected COM ports and write them to the prompt line.
HKEY hKey;
if (RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),&hKey)==ERROR_SUCCESS)
{
DWORD NumKeys;
DWORD i;
TCHAR KeyNameBuf[255];
DWORD keyNameSizBuf=255;
RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,NULL,NULL,&NumKeys,NULL,NULL,NULL,NULL);
for (i=0;i<NumKeys-1;i++)
{
keyNameSizBuf=15;
RegEnumKeyEx(hKey,i,KeyNameBuf,&keyNameSizBuf,NULL,NULL,NULL,NULL);
qDebug() <<KeyNameBuf;
}
}
The problem: it doesn't change the KeyNameBuf and keeps it null.
Any ideas?
Thank you, and sorry in advance if it is something trivial...
Solution found:
RegEnumKeyEx retrieve the data pointers (optional argument 7), and then convert int from Byte* to const char *

SetFilePointerEx fails to read physical disk beyond size of LONG

It's taken a few years, but I am finally taking the plunge into VC++. I need to be able to read x number of sectors of a physical device (namely a hard drive). I am using the CreateFile() and SetFilePointerEx() and ReadFile() APIs.
I have done a LOT of reading online in all the major forums about this topic. I have exhausted my research and now I feel it's time to ask the experts to weigh in on this dilemma. As this is my very first post ever on this topic, please go easy on my :)
I should also point out that this is a .DLL that I consume with a simple C# app. The plumbing all works fine. It's the SetFilePointer(Ex)() APIs that are causing me grief.
I can get the code to work up until about the size of a LONG (4,xxx,xxx) - I can't remember the exact value. It suffices to say that I can read everything up to and including sector # 4,000,000 but not 5,000,000 or above. The problem lies in the "size" of the parameters for the SetFilePointer() and SetFilePointerEx() APIs. I've tried both and so far, SetFilePointerEx() seems to be what I should use to work on 64-bit systems.
The 2nd and 3rd parameters of the SetFilePointer are defined as follows:
BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);
Please note that I have tried passing the LowPart and the HighPart as the 2nd and 3 parameters without any success as I get a CANNOT CONVERT LARGE_INTEGER TO PLARGE_INTEGER (for parameter 3).
HERE IS MY CODE. I USE A CODE-BREAK TO VIEW buff[0], etc. I would like to read past the 4,xxx,xxx limitation. Obviously I am doing something wrong. Each read past this limit resets my file pointer to sector 0.
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
extern "C"
__declspec(dllexport) int ReadSectors(long startSector, long numSectors)
{
HANDLE hFile;
const int SECTOR_SIZE = 512;
const int BUFFER_SIZE = 512;
LARGE_INTEGER liDistanceToMove;
PLARGE_INTEGER newFilePtr = NULL; // not used in this context.
// just reading from START to END
liDistanceToMove.QuadPart = startSector * SECTOR_SIZE;
DWORD dwBytesRead, dwPos;
LPCWSTR fname = L"\\\\.\\PHYSICALDRIVE0";
char buff[BUFFER_SIZE];
// Open the PHYSICALDEVICE as a file.
hFile = CreateFile(fname,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Here's the API definition
/*BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);*/
dwPos = SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);
if(ReadFile(hFile, buff, BUFFER_SIZE, &dwBytesRead, NULL))
{
if(dwBytesRead > 5)
{
BYTE x1 = buff[0];
BYTE x2 = buff[1];
BYTE x3 = buff[2];
BYTE x4 = buff[3];
BYTE x5 = buff[4];
}
}
// Close both files.
CloseHandle(hFile);
return 0;
}
startSector * SECTOR_SIZE;
startSector is a long (32bits), SECTOR_SIZE is a int (also 32bits), multiply these two guys and the intermediate result is going to be a long, which will overflow and you then stuff it into the __int64 of the LARGE_INTEGER, which is too late. You want to operate on __int64s, something like
liDistanceToMove.QuadPart = startSector;
liDistanceToMove.QuadPart *= SECTOR_SIZE;
for example.

Resources