一部のメモリ アドレスの読み取りに問題があります。"1C1F3400" のように "00" で終わる場合を除いて、ほとんどは問題なく動作します。
読み取り機能自体のコードは次のとおりです。¨
def readValue(self, address, bytes, outputType):
theValue = ctypes.create_string_buffer(bytes)
intAddress = int(address,16)
if(outputType == 'float'):
pass
if(outputType == 'string'):
bytes = 50
theValue = ctypes.create_string_buffer(bytes)
if self.rPM(self.PROCESS.handle,intAddress,theValue,bytes,None):
pass
else:
print 'Failed to read address ' + address
if(outputType == 'address'):
#print theValue.value
try:
return hex(struct.unpack('<L',theValue.value)[0])
except struct.error:
print str(theValue.value) + ' not valid'
self.memReadLog.write('Unreadable address at: ' + str(address) + '\n')
self.memReadLog.write('The value read was: ' + str(theValue.value) + '\n')
return 'error'
次に、時々失敗する部分のこのコードがあります。これは、プリセットポインターの配列を取り、それらすべてを通過した後に正しいアドレスを見つけます。モジュール アドレスは以前に検出され、クラス変数にあります。
def addressByPointer(self,initialAddress, bytes, offsetArray):
#print initialAddress
#print self.modAddress
currentAddress = self.addHex(initialAddress,self.modAddress)
#print currentAddress
OALength = len(offsetArray)
counter = 0
for offset in offsetArray:
print 'Before adding: CA: ' + currentAddress + ' Offset: ' + offset
currentAddress = self.addHex(currentAddress,offset)
print 'Read ' + currentAddress
if(counter == OALength-1):
return currentAddress
currentAddress = self.readValue(currentAddress,bytes,'address')
if(currentAddress == 'error'):
break
print ' .. and found ' + str(currentAddress)
counter += 1
これは、最後のアドレスから読み取った値の最後に 00 がない場合の動作です。
Before adding: CA: 1662aa4 Offset: 0x0
Read 1662aa4
.. and found 0x4743d30
Before adding: CA: 0x4743d30 Offset: 0x0
Read 4743d30
.. and found 0x19416408
そして、この値は期待される結果 (この場合は整数) を保持します。
しかし、時々私はこれを得る:
Read 1c1f46a8
.. and found 0x19416408
Before adding: CA: 0x19416408 Offset: 0x6B0
Read 19416ab8
not valid
Cheat Engine を使用して手動で値を読み取ると、1C1F3400 と等しくなるはずです。そして、そこからポインターチェーンをたどると、正常に機能し、最終結果は正しい値になります。ReadProcessMemory 関数はエラーを返しませんが (1 を返します)、rPM によって読み取られた値が 0 であるため、アンパックは失敗します。
失敗したアドレスには常に最後に 00 があるため、読み取りが早期に停止すると推測していますか? これを回避する方法や、私が犯している明らかな間違いはありますか? あるいは、私の仮定が間違っているかもしれません。
他にも間違いがあるかもしれません。バイトを解凍すると混乱します。私は他の多くの質問を読みましたが、それらのほとんどは、間違ったハンドルまたはrPM関数によって返された別のエラーが原因でメモリ読み取りが失敗したことに関するものです。この場合、成功すると表示されますが、出力は0です(戻り値ではありません) 「theValue」を出力すると、それが0になることがわかります(したがって、アンパックは失敗します)。また、これらの値を除いて正しく機能します。
確認するためにテストしましたが、値 0x1B334D00、0x04DA8300 および 00 で終わる他の値を見つけることにも失敗しました。3 バイトを読み取って最後に 00 を追加するようなことはできますか? ? それ以外に、「theValue」の型が間違っているか、struct.unpack 引数が間違っている可能性があります。
私はたくさん検索しましたが、途中でいくつかの明らかな答えを見落としている可能性があります。
編集:私がしているのは、正しいメモリアドレスに到達するためにポインター値を読み取ることです。オフセットと初期アドレス、および探している各アドレスのモジュール アドレスが格納されています。失敗する人は毎回違います。したがって、読み取りごとにポインターアドレスが返されるはずです。次に、それにオフセットを追加して、次のアドレスを取得します。しかし、特にポインターが 00 で終わる 16 進アドレスを持っている場合は、途中で失敗することがあります。その後、ReadProcessMemory はアドレスの代わりに何も返しません (エラーではなく、何も返しません)。他のツールを使用すると表示されるため、アドレスがそこにあることは知っていますが、ここで使用されている方法では、アドレスの代わりに何も返されず、理由がわかりません。構造体の使用法は問題ないはずです。問題は ReadProcessMemory にあると思います。
構造体エラーには、「unpack には長さ 4 の文字列引数が必要です」と書かれています。これは、ReadProcessMemory が何も返さなかったためだと思います。値が 0 のアドレスを読み取って struct.unpack を使用すると、同じエラーが発生します。これは正常だと思いました。