Jump to content


 


Register a free account to unlock additional features at BleepingComputer.com
Welcome to BleepingComputer, a free community where people like yourself come together to discuss and learn how to use their computers. Using the site is easy and fun. As a guest, you can browse and view the various discussions in the forums, but can not create a new topic or reply to an existing one unless you are logged in. Other benefits of registering an account are subscribing to topics and forums, creating a blog, and having no ads shown anywhere on the site.


Click here to Register a free account now! or read our Welcome Guide to learn how to use this site.

Photo

C Pointer Noob


  • Please log in to reply
15 replies to this topic

#1 chx101

chx101

  • Members
  • 32 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:uSa
  • Local time:06:08 AM

Posted 25 June 2009 - 03:13 PM

Hie im wiriting program in Dev C++ that changes a value in process' an address.

the program works fine if i insert the address directly in it

for example the Process winmine.exe which is Minesweeper keeps its time at the address 0x0100579C

Now i want my exe to use parameters in this format
prog.exe [Process Window name] [Address] [New Value]
the code is
int main (int argc, char* argv[])
{
//everything works well all i need help on is how to convert argv[2] which is argument number 2, to a pointer to store
//an address like 0x0100579C , entered from the commandline

}


i have to say i suck at pointers..lol
any help will be greatly appreciated , thanks.

Edited by chx101, 25 June 2009 - 03:16 PM.


BC AdBot (Login to Remove)

 


#2 Billy O'Neal

Billy O'Neal

    Visual C++ STL Maintainer


  • Malware Response Team
  • 12,304 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:Redmond, Washington
  • Local time:04:08 AM

Posted 25 June 2009 - 05:35 PM

You cannot access the memory of another process without interfacing with Windows NT's memmory manager. Attempting to read or write to another processes memory is an error. Period. It's called an Access Violation .. you'd be attempting to access memory your program has not gotten rights to look at.

Plus, you have no way of knowing what address the time for minesweeper will be located when it runs -- the Windows NT kernel is free to move memory like this around. If you've used a debugger and have gotten a number like 0x0100579C, what you've actually gotten is an offset... a distance from the start bound of a process' memory region to the value you are viewing. And even if you have the correct offset, most applications won't have the same value stored in the same place every time -- dynamic memory is a huge part of modern applications.

If you want to view another process.. you can't do it the way you are describing. First you have to select the other process, modify your own process to get permissions to talk to the Windows NT kernel, get a handle to the other process, and then use the functions ReadProcessMemory and WriteProcessMemory to access anything outside your own process.

Sorry, but Windows is designed to prevent precisely what you're trying to do.

Billy3
Twitter - My statements do not establish the official position of Microsoft Corporation, and are my own personal opinion. (But you already knew that, right?)
Posted Image

#3 chx101

chx101
  • Topic Starter

  • Members
  • 32 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:uSa
  • Local time:06:08 AM

Posted 25 June 2009 - 05:49 PM

everything works fine all i need is to convert Char* argv[2] which is arguments number 2 as in Int Main(int argc, char* argv[]).. i want to convert it to be a pointer so when i put a process address/offset like 0x0100579C from the commandline it should be passed as a pointer

#4 Billy O'Neal

Billy O'Neal

    Visual C++ STL Maintainer


  • Malware Response Team
  • 12,304 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:Redmond, Washington
  • Local time:04:08 AM

Posted 25 June 2009 - 06:18 PM

What I'm trying to tell you is that that is not possible.

Billy3

EDIT: Reading from other processes is possible, but it's not just as simple as reading an address. You'd need to come up with a programatic way of doing it because the value you seek will change while the program is running.

Edited by Billy O'Neal, 25 June 2009 - 06:19 PM.

Twitter - My statements do not establish the official position of Microsoft Corporation, and are my own personal opinion. (But you already knew that, right?)
Posted Image

#5 Romeo29

Romeo29

    Learning To Bleep


  • Members
  • 3,194 posts
  • OFFLINE
  •  
  • Gender:Not Telling
  • Location:127.0.0.1
  • Local time:06:08 AM

Posted 25 June 2009 - 06:50 PM

You cannot pass a pointer in a command line. What you can pass is the value of a memory address. A memory address is just a DWORD value, you need to convert String to DWORD.

You will have to make a for loop going over the string value and adding corresponding numbers in a DWORD value initially set to 0. Figure that out :thumbsup:

As Billy O'Neal has said, the memory address is dynamically allocated and will change each time a program is run. If you try to hardcode it, you will be making changes in some random program.

#6 chx101

chx101
  • Topic Starter

  • Members
  • 32 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:uSa
  • Local time:06:08 AM

Posted 25 June 2009 - 08:55 PM

ok so how do i convert a string to DWORD : something like 0x0100579C

can these work :
DWORD* dwMVal;dwMVal = (DWORD*)argv[2];//?

Edited by chx101, 25 June 2009 - 08:59 PM.


#7 Billy O'Neal

Billy O'Neal

    Visual C++ STL Maintainer


  • Malware Response Team
  • 12,304 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:Redmond, Washington
  • Local time:04:08 AM

Posted 25 June 2009 - 10:11 PM

No. Romeo29 already answered your questoin, if you'd spend the 5 seconds to read it.

Billy3
Twitter - My statements do not establish the official position of Microsoft Corporation, and are my own personal opinion. (But you already knew that, right?)
Posted Image

#8 Score_Under

Score_Under

  • Members
  • 18 posts
  • OFFLINE
  •  
  • Local time:12:08 PM

Posted 26 July 2009 - 08:57 AM

EDIT- Wow, just looked at the dates, seems this forum section is very inactive.

@Billy O'Neal: Not possible, eh? Win32 API has a thing or 2 to say about that.
@Romeo29: The address is not dynamically allocated, it is actually a specific location in WinMine's data section (mainly used for global variables), so it's relative to the module handle.

A very hastily modified version of some code I wrote a long time ago to achieve a similar goal:
#include <windows.h>
#include <psapi.h>

void ToLower(char*a)
{
  register int i;
  register int j;
  j=strlen(a);
  for (i=0;i<j;i++)
	if (a[i]>='A'&&a[i]<='Z')
	  a[i]+='a'-'A';
  return;
}
int startswithi(char*haystack,char*needle)
{
  char*a;
  int ret;
  a=malloc(strlen(haystack)+1);
  strcpy(a,haystack);
  a[strlen(needle)]=0;
  ToLower(a);
  ret=!strcmp(a,needle);
  free(a);
  return ret;
}
int main()
{
  DWORD aProcesses[1024],cbNeeded,cProcesses,pid,read;
  unsigned int i;
  HANDLE process;
  HMODULE module;
  char procname[MAX_PATH]="";
  unsigned int data,modpoint;

  if (!EnumProcesses(aProcesses,sizeof(aProcesses),&cbNeeded))
	return 0;

  cProcesses=cbNeeded/sizeof(DWORD);
  pid=0;
  for (i=0;i<cProcesses;i++)
  {
	if (aProcesses[i]!=0)
	{
	  process=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,0,aProcesses[i]);
	  if (process!=NULL)
	  {
		if (EnumProcessModules(process,&module,sizeof(module),&cbNeeded))
		{
		  GetModuleBaseName(process,module,procname,MAX_PATH);
		}
		CloseHandle(process);
		if (startswithi(procname,"winmine"))
		{
		  pid=aProcesses[i];
		  break;
		}
	  }
	}
  }
  if (pid==0)
  {
	MessageBox(NULL,"Could not find WinMine.","Error",0x10);
	return 0;
  }
  process=OpenProcess(PROCESS_VM_OPERATION| PROCESS_QUERY_INFORMATION| PROCESS_VM_READ| PROCESS_VM_WRITE, 0, pid);
  if (process==NULL)
  {
	MessageBox(NULL,"WinMine unexpectedly terminated (?)","Error",0x10);
	return 0;
  }
  if (!EnumProcessModules(process,&module,sizeof(module),&cbNeeded))
  {
	MessageBox(NULL,"Could not get WinMine's module handle.","Error",0x10);
	CloseHandle(process);
	return 0;
  }
  modpoint=(unsigned int)module;
  modpoint+=0x579C; //0x0100579C
  if (!ReadProcessMemory(process,(void*)modpoint,&data,sizeof(data),&read))
  {
	i=GetLastError();
	MessageBox(NULL,"Could not read WinMine's memory.","Error",0x10);
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,i,0,procname,sizeof(procname),NULL);
	MessageBox(NULL,procname,"Description",0);
	CloseHandle(process);
	return 0;
  }
  data=0; //Reset the timer to zero
  if (!WriteProcessMemory(process,(void*)modpoint,&data,sizeof(data),&read))
  {
	MessageBox(NULL,"Could not write to WinMine's memory.","Error",0x10);
	CloseHandle(process);
	return 0;
  }
  MessageBox(NULL,"Success!","Go wild!",0x40);
  CloseHandle(process);
  return 0;
}
I wrote this for use with MinGW, the command line is:
gcc -o ptr.exe ptr.c -Os -s -lpsapi
If you're using Dev-C++, Code::Blocks, MSVC++, etc., then you'll need to find somewhere in the project settings how to add psapi to your libraries you are linking to (if you have to find it in a bunch of files, it'll probably be "psapi.lib" or "libpsapi.a").

Edited by Score_Under, 26 July 2009 - 09:06 AM.


#9 Romeo29

Romeo29

    Learning To Bleep


  • Members
  • 3,194 posts
  • OFFLINE
  •  
  • Gender:Not Telling
  • Location:127.0.0.1
  • Local time:06:08 AM

Posted 26 July 2009 - 06:36 PM

The asker did not specify that it was relative address in the module he/she wanted to patch. The main module address would be dynamic anyway.

You have written a lot of code for something which can be achieved by simple WIN32 API. You can remove all enumeration and two functions you wrote, to get winmine.exe's process id by these two functions:

1. FindWindow to find Minesweeper window handle.
2. GetWindowThreadProcessId to get the process id using the window handle.

Thanks for clearing up and sharing the information :thumbsup:

Edited by Romeo29, 26 July 2009 - 06:38 PM.


#10 wj32

wj32

  • Members
  • 56 posts
  • OFFLINE
  •  
  • Local time:10:08 PM

Posted 29 July 2009 - 03:45 AM

The asker did not specify that it was relative address in the module he/she wanted to patch. The main module address would be dynamic anyway.


I wouldn't think that MS would dynamically allocate structures for each game, considering the usual C programming style and the fact that it doesn't support more than one game at once. As for the dynamic main module address... MS has cleverly set up all preferred image bases so that almost all executables shipped with Windows do not require image base relocation. And even if it was relocated, you could still enumerate the process' modules.
MCTS: Windows Internals.
Stupid bureaucracy.

#11 wj32

wj32

  • Members
  • 56 posts
  • OFFLINE
  •  
  • Local time:10:08 PM

Posted 29 July 2009 - 03:47 AM

The asker did not specify that it was relative address in the module he/she wanted to patch. The main module address would be dynamic anyway.


I wouldn't think that MS would dynamically allocate structures for each game, considering the usual C programming style and the fact that it doesn't support more than one game at once. As for the dynamic main module address... MS has cleverly set up all preferred image bases so that almost all executables shipped with Windows do not require image base relocation. And even if it was relocated, you could still enumerate the process' modules. You're making it seem harder than it is :thumbsup:.

As for converting a string to an integer, why not use atoi?
MCTS: Windows Internals.
Stupid bureaucracy.

#12 Billy O'Neal

Billy O'Neal

    Visual C++ STL Maintainer


  • Malware Response Team
  • 12,304 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:Redmond, Washington
  • Local time:04:08 AM

Posted 01 August 2009 - 05:21 PM

I wouldn't think that MS would dynamically allocate structures for each game, considering the usual C programming style and the fact that it doesn't support more than one game at once. As for the dynamic main module address... MS has cleverly set up all preferred image bases so that almost all executables shipped with Windows do not require image base relocation.

Actually, this is done with DLLs, but not for the EXEs.

The point is, even if you can get the right address, NT will not allow you to "just read" the memory. The second your app reads from an arbitrary location, it is exhibiting undefined behavior. On Windows NT (and 2k, XP, Vista, 7, etc) , this is an access violation, and if you read from another process' address space without going through the OS first, your process will be terminated. You need to use the readprocesmemory and writeprocessmemory as specified above. Pointer addresses in Windows NT are only valid inside your own process. Attempting to read from another process will cause termination.

Billy3
Twitter - My statements do not establish the official position of Microsoft Corporation, and are my own personal opinion. (But you already knew that, right?)
Posted Image

#13 Score_Under

Score_Under

  • Members
  • 18 posts
  • OFFLINE
  •  
  • Local time:12:08 PM

Posted 02 August 2009 - 11:29 AM

The asker did not specify that it was relative address in the module he/she wanted to patch. The main module address would be dynamic anyway.


I wouldn't think that MS would dynamically allocate structures for each game, considering the usual C programming style and the fact that it doesn't support more than one game at once. As for the dynamic main module address... MS has cleverly set up all preferred image bases so that almost all executables shipped with Windows do not require image base relocation. And even if it was relocated, you could still enumerate the process' modules.

I got the main module handle of the process anyway, as the address in this case is always relative to it. If it dynamically allocates memory anyway, you can easily just make another call to ReadProcessMemory.

#14 Romeo29

Romeo29

    Learning To Bleep


  • Members
  • 3,194 posts
  • OFFLINE
  •  
  • Gender:Not Telling
  • Location:127.0.0.1
  • Local time:06:08 AM

Posted 02 August 2009 - 04:37 PM

I got the main module handle of the process anyway, as the address in this case is always relative to it. If it dynamically allocates memory anyway, you can easily just make another call to ReadProcessMemory.


Your aim is to patch memory and set the time counter to 0. Why would you read memory? Just write into memory, if successful, fine; else pop-up some error message.

#15 chx101

chx101
  • Topic Starter

  • Members
  • 32 posts
  • OFFLINE
  •  
  • Gender:Male
  • Location:uSa
  • Local time:06:08 AM

Posted 12 August 2009 - 08:34 PM

thank you WJ32




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users