Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
scanmem(1)		    General Commands Manual		    scanmem(1)

       scanmem - locate	and modify variables in	an executing process.

       scanmem [options] [target-program-pid]

       scanmem is an interactive debugging utility that	can be used to isolate
       the address of a	variable in an executing process by successively scan-
       ning the	process' address space looking for matching values.
       By  informing  scanmem how the value of the variable changes over time,
       it can determine	the actual location (or	locations) of the variable  by
       successively eliminating	non-matches.
       scanmem	determines  where  to  look  by	 searching  for	 mappings with
       read/write permission, these are	referred  to  as  regions.  Users  can
       eliminate regions they believe are likely unrelated to the target vari-
       able (for example, located in a shared library unrelated	to  the	 vari-
       able  in	 question), this will improve the speed	of the scan, which can
       initially be quite slow in large	programs.

       Once a variable has been	found, scanmem can monitor  the	 variable,  or
       change it to a user specified value, either once, or continually	over a
       period of time.

       scanmem works similarly to the  "pokefinders"  once  commonly  used  to
       cheat  at  video	games, this function is	a good demonstration of	how to
       use scanmem, and	is used	in the documentation.

       scanmem should be invoked with the process id of	the program  you  wish
       to  debug  as  an  argument.  Once started, scanmem accepts interactive
       commands.  These	are described below, however entering help  at	the  >
       prompt will allow you to	access scanmem's online	documentation.

       The target-program-pid can be specified in decimal, hexadecimal,	or oc-
       tal using the standard C	language notation (leading 0x for hexadecimal,
       leading 0 for octal, anything else is assumed to	be decimal).

       -p, --pid=pid
	      Set the target-program-pid.

       -c, --command=cmd1[;cmd2][;...]
	      Run given	commands (separated by ";") before starting the	inter-
	      active shell.

       -v, --version
	      Print version and	exit.

       -h, --help
	      Print a short description	of command line	options	then exit.

       -d, --debug
	      Run in debug mode, more information will be outputted.

       -e, --errexit
	      Exit on initial commands error, ignored during interactive mode.

       While in	interactive mode, scanmem prints a decimal number followed  by
       >, the number is	the current number of possible candidates for the tar-
       get variable that are known. The	absence	of said	number indicates  that
       no possible variables have been eliminated yet.
       The default scan	data type is "int".  It	can be changed with the	option

       n      Where n represents any number in decimal,	octal or  hexadecimal,
	      this  command tells scanmem that the current value of the	target
	      variable is exactly n.  scanmem will begin a search of  the  en-
	      tire  address  space,  or	 the  existing known matches (if any),
	      eliminating any variable that does not have this value.

       n..m   This is like the n command but scanmem searches for a  range  of
	      numbers between n	and m inclusive	instead.

       >, <, +,	-, =, !=
	      The following commands are extremely useful for locating a vari-
	      able whose exact value we	cannot see, but	 we  can  see  how  it
	      changes  over  time, e.g.	an health bar.	These commands usually
	      cannot be	used for the first scan	but there are some exceptions:
	      >	n, < n,	= n and	!= n.

	      >	[n]  If	 n  is	given,	match  values that are greater than n.
		     Otherwise match all values	that have increased.

	      <	[n]  If	n is given, match values that are less than n.	Other-
		     wise match	all values that	have decreased.

	      +	[n]  If	 n  is given, match values that	have been increased by
		     n.	 Otherwise match all values that have increased	 (same
		     as	>).

	      -	[n]  If	 n  is given, match values that	have been decreased by
		     n.	 Otherwise match all values that have decreased	 (same
		     as	<).

	      =	[n]  If	 n is given, match values that are equal to n (same as
		     n). Otherwise match all values that have not changed.

	      != [n] If	n is given, match values that are  different  from  n.
		     Otherwise match all values	that have changed.

	      Match  any  value. This is useful	when an	initial	value or range
	      is not known for subsequent scans	with >,	<, +, -, =, and	!=.

       " text Search for the provided text in memory if	the scan data type  is
	      set to "string".

       update Scans  the  current  process,  getting the current values	of all
	      matches. These values can	be viewed with list, and are also  the
	      old values that scanmem compares to when using >,	<, or =.  This
	      command is equivalent to a search	command	that all  current  re-
	      sults match.

       list [max_to_print]
	      List  up to max_to_print (default: 10k) possible candidates cur-
	      rently known, including their address, region id,	match  offset,
	      region  type,  last  known  value	and possible value types.  The
	      value in the first column	is the match id, and can  be  used  in
	      conjunction with the delete command to eliminate matches.

	      The  match  offset is determined by subtracting the load address
	      of the associated	ELF file or region from	the address. It	can be
	      used to bypass Address Space Layout Randomization	(ASLR).

       delete match-id_set
	      Delete  matches in the match-id_set.  The	match-ids can be found
	      from  the	 output	 of   the   list   command.    Set   notation:
	      [!][..a](,b..c | d, ...)[e..].
	      To delete	all known matches, see the reset command.
	      To  delete all the matches associated with a particular library,
	      see the dregion  command,	 which	also  removes  any  associated
	      Please note that match-ids may be	recalculated after matches are
	      removed or added.

       watch match-id
	      Monitor the value	 of  match-id,	and  print  its	 value	as  it
	      changes. Every change is printed along with a timestamp, you can
	      interrupt	this command with ^C to	stop monitoring.

       set [match-id_set=]value[/delay]	[...]
	      Set the value value into the match numbers specified  in	match-
	      id_set, or if just value is specified, all known matches.	 value
	      can be specified in standard C  language	notation.   All	 known
	      matches,	along with their match-id's can	be displayed using the
	      list command.  Multiple match-id_sets can	be  specified,	termi-
	      nated  with  an  =  sign.	  Set  notation:  [!][..a](,b..c  | d,
	      To set a value continually, suffix the command with  /  followed
	      by the number of seconds to wait between sets. You can interrupt
	      the set command with ^C to return	to the scanmem	prompt.	  This
	      can  be  used to sustain the value of a variable which decreases
	      over time, for example a timer that is decremented every	second
	      can be set to 100	every 10 seconds to prevent some property from
	      ever changing.

	      This command is used to change the value of the variable(s) once
	      found by elimination.  Please note, some applications will store
	      values in	multiple locations.

       write value_type	address	value
	      Manually set the value of	the variable at	the specified address.
	      Names of value_type are subject to change	in different  versions
	      of scanmem, see more info	using the `help	write` command.

       dump address length [filename]
	      Dump the memory region starting from address of length length in
	      a	human-readable format.

	      If filename is given, data will be saved into the	 file,	other-
	      wise data	will be	displayed on stdout.

       pid [new-pid]
	      Print  out  the  process	id  of	the current target program, or
	      change the target	to new-pid, which will reset existing  regions
	      and matches.

       reset  Forget all known regions and matches and start again.

	      List all the known regions, this can be used in combination with
	      the dregion command to eliminate regions that the	user  believes
	      are  not	related	to the variable	in question, thus reducing the
	      address space required to	search in. The value in	the first col-
	      umn  is  the  region-id which must be passed to the dregion com-
	      mand. Besides the	start address, the size	and path (if  applica-
	      ble) are also printed. This can be used to eliminate regions lo-
	      cated in shared libraries	that are unlikely to  be  relevant  to
	      the variable required.

	      For  experts: Also the region type and the load address are dis-
	      played. The  types  are  "exe"  (executable)  "code"  (library),
	      "heap", "stack" or "misc"	(everything else). The load address is
	      the memory location where	an ELF file (exe/lib) has been	loaded
	      to. This helps to	convert	between	the addresses in memory	and in
	      the associated ELF file. If the region does not belong to	an ELF
	      file, then it is the same	as the start address.

       dregion region-id_set
	      Delete the regions in region-id_set, along with any matches from
	      the match	list.  Set notation: [!][..a](,b..c | d, ...)[e..].
	      The region-id's can be found in the output of the	lregions  com-

       option name value
	      Change  options  at  runtime.  E.g.  the	scan  data type	can be
	      changed.	See `help option` for all possible names/values.

       shell shell-command
	      Execute shell-command using /bin/sh, then	return.

       show info
	      Display information relating to info - see `help show`  for  de-

	      Print the	version	of scanmem in use.

       help   Print a short summary of available commands.

       exit   Detach from the target program and exit immediately.

       Cheat at	nethack, on systems where nethack is not installed sgid.

       ATTENTION:  scanmem  usually requires root privileges. See KNOWN	ISSUES
       for details.

       $ sudo scanmem `pgrep nethack`
       info: maps file located at /proc/14658/maps opened.
       info: 9 suitable	regions	found.
       Please enter current value, or "help" for other commands.

       I enter how much	gold I currently have (58 pieces) and let scanmem find
       the potential candidates.

       > 58
       01/09 searching	 0x79f000 -   0x7b0000..........ok
       02/09 searching	 0x7b0000 -   0x7cc000..........ok
       03/09 searching	0x24d2000 -  0x24f3000..........ok
       04/09 searching 0x7fcc04baa000 -	0x7fcc04bae000..........ok
       05/09 searching 0x7fcc04de1000 -	0x7fcc04de2000..........ok
       06/09 searching 0x7fcc051f7000 -	0x7fcc051fb000..........ok
       07/09 searching 0x7fcc05227000 -	0x7fcc0522a000..........ok
       08/09 searching 0x7fcc0522c000 -	0x7fcc0522d000..........ok
       09/09 searching 0x7ffc8c113000 -	0x7ffc8c134000..........ok
       info: we	currently have 16 matches.
       16> list
       [ 0]	  7b09e0,  1 +	     3b09e0,   exe, 58,	[I64 I32 I16 I8	]
       [ 1]	  7b907a,  1 +	     3b907a,   exe, 58,	[I8 ]
       [ 2]	 24d4b6c,  2 +	       2b6c,  heap, 58,	[I16 I8	]
       [ 3]	 24d567e,  2 +	       367e,  heap, 58,	[I16 I8	]
       [ 4]	 24d5740,  2 +	       3740,  heap, 58,	[I8 ]
       [ 5] 7fcc05229951,  6 +	       2951,  misc, 58,	[I8 ]
       [ 6] 7ffc8c12ee28,  8 +	      1be28, stack, 58,	[I16 I8	]
       [ 7] 7ffc8c132381,  8 +	      1f381, stack, 58,	[I8 ]
       [ 8] 7ffc8c132389,  8 +	      1f389, stack, 58,	[I8 ]
       [ 9] 7ffc8c132391,  8 +	      1f391, stack, 58,	[I8 ]
       [10] 7ffc8c132399,  8 +	      1f399, stack, 58,	[I8 ]
       [11] 7ffc8c1323a1,  8 +	      1f3a1, stack, 58,	[I8 ]
       [12] 7ffc8c1323a9,  8 +	      1f3a9, stack, 58,	[I8 ]
       [13] 7ffc8c1331a3,  8 +	      201a3, stack, 58,	[I8 ]
       [14] 7ffc8c13325f,  8 +	      2025f, stack, 58,	[I8 ]
       [15] 7ffc8c133264,  8 +	      20264, stack, 58,	[I8 ]

       16  potential matches were found. This is also displayed	in the prompt.
       Many of them are	quite unrelated, as they are part of the stack,	belong
       to libraries or miscellaneous memory-mapped files. Even the heap	is un-
       likely for a very old command line game.	We could make  scanmem	elimi-
       nate  these manually using the delete command, however just waiting un-
       til the amount of gold changes and telling scanmem the new value	should
       be enough. I find some more gold, and tell scanmem the new value, 83.

       16> 83 we currently have 1 matches.
       info: match identified, use "set" to modify value.
       info: enter "help" for other commands.
       1> list
       [ 0]	  7b09e0,  1 +	     3b09e0,   exe, 83,	[I64 I32 I16 I8	]

       Only  one  of  the 16 original candidates now has the value 83, so this
       must be where the amount	of gold	is stored.  I'll  try  setting	it  to
       10,000 pieces.

       1> set 10000
       info: setting *0x7b09e0 to 0x2710...

       The resulting nethack status:

       Dlvl:1  $:10000 HP:15(15) Pw:2(2) AC:7  Exp:1

       Conclusion:  We've  found  and modified the gold	value as I32 in	static
       memory of the executable	at virtual memory address 0x7b09e0.  This  ad-
       dress belongs to	the region with	id 1.

       Now  it	is  important  to  know	if this	is a position-independent exe-
       cutable (PIE). We list the regions for this and check the load  address
       of the executable.

       1> lregions
       [ 0]	  79f000,   69632 bytes,   exe,	      400000, rw-, /usr/lib/nethack/nethack.tty
       [ 1]	  7b0000,  114688 bytes,   exe,	      400000, rw-, unassociated
       [ 2]	 24d2000,  135168 bytes,  heap,	     24d2000, rw-, [heap]
       [ 3] 7fcc04baa000,   16384 bytes,  misc,	7fcc04baa000, rw-, unassociated
       [ 4] 7fcc04de1000,    4096 bytes,  misc,	7fcc04de1000, rw-, unassociated
       [ 5] 7fcc051f7000,   16384 bytes,  misc,	7fcc051f7000, rw-, unassociated
       [ 6] 7fcc05227000,   12288 bytes,  misc,	7fcc05227000, rw-, unassociated
       [ 7] 7fcc0522c000,    4096 bytes,  misc,	7fcc0522c000, rw-, unassociated
       [ 8] 7ffc8c113000,  135168 bytes, stack,	7ffc8c113000, rw-, [stack]

       We  are	on x86_64 and 0x400000 is the static load address for executa-
       bles there. This	means that this	is not a PIE and the  gold  is	always
       stored at 0x7b09e0. This	makes it easy to use a game trainer like Game-
       Conqueror which refills the gold	value periodically.

       With a PIE we have to use the match offset (0x3b09e0 here) instead  and
       an  advanced game trainer with PIE support has to determine and add the
       current load address to it to get the current  memory  address  of  the
       gold value of the current game run.

       scanmem	has  been  tested on multiple large programs, including	the 3d
       shoot-em-up quake3 linux.  scanmem is also tested on ARM	platforms  and
       comes with Android support since	version	0.16.

       Obviously, scanmem can crash your program if used incorrectly.

       Some  programs store values in multiple locations, this is why set will
       change all known	matches.

       Address Space Layout Randomization (ASLR) together with	position-inde-
       pendent	executables  (PIE), position-independent code (PIC) or dynamic
       memory on the heap causes variables to be loaded	 to  different	memory
       addresses  at every game	start. Advanced	game trainers like ugtrain are
       required	to periodically	refill variables is such memory	regions.

       scanmem usually requires	root privileges	for ptrace(2) because security
       modules	control	ptrace() capabilities. On x86 and x86_64 there is usu-
       ally  the  Yama	security  module  providing  the  file	/proc/sys/ker-
       nel/yama/ptrace_scope.	It  is available since Linux 3.4. If this file
       contains	"1", then only parents may  ptrace()  their  children  without
       root  privileges.  This	means that scanmem would have to run the game.
       This is not possible as this would require major	design changes.	So  we
       run scanmem as root.

       The  first scan can be very slow	on large programs, this	is not a prob-
       lem for subsequent scans	as huge	portions of the	address	space are usu-
       ally  eliminated. This could be improved	in future, perhaps by assuming
       all integers are	aligned	by default. Suggestions	welcome.

       The snapshot command uses memory	inefficiently, and should probably not
       be used on large	programs.


       Tavis Ormandy <taviso(a)>
       Eli   Dupree  <elidupree(a)>
       WANG  Lu	     <coolwanglu(a)>
       Sebastian Parschauer <s.parschauer(a)>
       Andrea Stacchiotti <andreastacchiotti(a)>

       All bug reports,	suggestions or feedback	welcome.

       gameconqueror(1)	ptrace(2) proc(5) nethack(6) pidof(8)

scanmem-0.17			  2017-10-11			    scanmem(1)


Want to link to this manual page? Use this URL:

home | help