1+ package com .beaudoin .jmm .process .impl .unix ;
2+
3+ import com .beaudoin .jmm .misc .Cacheable ;
4+ import com .beaudoin .jmm .misc .MemoryBuffer ;
5+ import com .beaudoin .jmm .natives .unix .uio ;
6+ import com .beaudoin .jmm .process .Module ;
7+ import com .beaudoin .jmm .process .NativeProcess ;
8+ import com .sun .jna .Pointer ;
9+
10+ import java .io .IOException ;
11+ import java .nio .file .Files ;
12+ import java .nio .file .Paths ;
13+ import java .util .HashMap ;
14+ import java .util .Map ;
15+
16+ /**
17+ * Created by Jonathan on 1/10/2016.
18+ */
19+ public final class UnixProcess implements NativeProcess {
20+
21+ private uio .iovec local = new uio .iovec ();
22+ private uio .iovec remote = new uio .iovec ();
23+
24+ private final int id ;
25+ private final Pointer handle ;
26+ private Map <String , Module > modules = new HashMap <>();
27+
28+ public UnixProcess (int id , Pointer handle ) {
29+ this .id = id ;
30+ this .handle = handle ;
31+ initModules ();
32+ }
33+
34+ @ Override
35+ public int id () {
36+ return id ;
37+ }
38+
39+ @ Override
40+ public Pointer pointer () {
41+ return handle ;
42+ }
43+
44+ @ Override
45+ public void initModules () {
46+ try {
47+ for (String line : Files .readAllLines (Paths .get ("/proc/" + id () + "/maps" ))) {
48+ String [] split = line .split (" " );
49+ String [] regionSplit = split [0 ].split ("-" );
50+
51+ long start = Long .parseLong (regionSplit [0 ], 16 );
52+ long end = Long .parseLong (regionSplit [1 ], 16 );
53+ long offset = Long .parseLong (split [2 ], 16 );
54+ if (offset <= 0 ) {
55+ continue ;
56+ }
57+ String path = "" ;
58+ for (int i = 5 ; i < split .length ; i ++) {
59+ String s = split [i ].trim ();
60+ if (!s .isEmpty ()) {
61+ path += split [i ];
62+ }
63+ if (s .isEmpty () && ++i > split .length ) {
64+ break ;
65+ } else if (s .isEmpty () && !split [i ].trim ().isEmpty ()) {
66+ path += split [i ];
67+ }
68+ }
69+ String modulename = path .substring (path .lastIndexOf ("/" ) + 1 , path .length ());
70+ modules .put (modulename , new Module (this , modulename , Pointer .createConstant (start ), end - start ));
71+ }
72+ } catch (IOException e ) {
73+ e .printStackTrace ();
74+ }
75+ }
76+
77+ @ Override
78+ public Module findModule (String moduleName ) {
79+ return modules .get (moduleName );
80+ }
81+
82+ @ Override
83+ public MemoryBuffer read (Pointer address , int size ) {
84+ MemoryBuffer buffer = Cacheable .buffer (size );
85+ local .iov_base = buffer ;
86+ remote .iov_base = address ;
87+ remote .iov_len = local .iov_len = size ;
88+ if (uio .process_vm_readv (id , local , 1 , remote , 1 , 0 ) != size ) {
89+ throw new RuntimeException ("Read memory failed at address " + Pointer .nativeValue (address ) + " size " + size );
90+ }
91+ return buffer ;
92+ }
93+
94+ @ Override
95+ public NativeProcess write (Pointer address , MemoryBuffer buffer ) {
96+ local .iov_base = buffer ;
97+ remote .iov_base = address ;
98+ remote .iov_len = local .iov_len = buffer .size ();
99+ if (uio .process_vm_writev (id , local , 1 , remote , 1 , 0 ) != buffer .size ()) {
100+ throw new RuntimeException ("Read memory failed at address " + Pointer .nativeValue (address ) + " size " + buffer .size ());
101+ }
102+ return this ;
103+ }
104+
105+ @ Override
106+ public boolean canRead (Pointer address , int size ) {
107+ try {
108+ read (address , size );
109+ return true ;
110+ } catch (Exception e ) {
111+ return false ;
112+ }
113+ }
114+
115+ }
0 commit comments