Skip to content
This repository was archived by the owner on May 24, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pogom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
],
'ROOT_PATH': None,
'CONFIG_PATH': None,
'SIGNATURE_LIB_PATH': None
'SIGNATURE_LIB_PATH': None,
'HASH_LIB_PATH': None
}
21 changes: 21 additions & 0 deletions pogom/lib/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2016 PokéLibs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
69 changes: 69 additions & 0 deletions pogom/lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[PokéLibs](https://github.com/pokelibs)

# pgoapi-libs
[![license](https://img.shields.io/github/license/pokelibs/pgoapi-libs.svg?maxAge=2592000?style=flat-square)](https://github.com/pokelibs/pgoapi-libs/blob/master/LICENSE.md)

## Table of Contents

* [What is it?](#what-is-it)
* [Installation](#installation)
* [Documentation](#documentation)
* [Contributing](#contributing)
* [Core Maintainers](#core-maintainers)
* [Licensing](#licensing)

## What is it?
`pgoapi-libs` is the official source repository for all hashing, encrypt and future libraries that need to be shipped with various API implementations.

## Installation
Simply checkout this repository as a submodule for your project at the desired tagged release.
Please make sure that the SHA256SUMS match up with the sums for each file to assure it hasn't been tampered with.
The latest sums are:

```
b8f62a0fbb301eabbe4cb83bab2c17f35360116b46e196fd53ef5da1d7d1395d libniahash-freebsd-i386.so
3ffbc2f64ffda74c82cefeff94a7d3aeba72efcc890b847ff2732c308768e6dd libniahash-freebsd-x86-64.so
e1eff1af978b0fda2b883d38c53290c15de3ca4274b4bd8690d41eab8558843b libniahash-linux-arm32.so
8fcb0424682df55684410ebb078adc467842f2cf4d2c1b5cc757e461388671df libniahash-linux-arm64.so
c194a4207eabf0f3e2b418e39747dabeb63aba397a73b27c64eb064e9b344d83 libniahash-linux-i386.so
dd1e9510e58f2793f3f92ec352c8d301e797be473c8aa00d731e5d931f0f76b2 libniahash-linux-x86-64.so
c6985404f10dd5daab8458c80432ae773b4ac2d8129fcbd05c25668e199d5882 libpcrypt-freebsd-i386.so
a6f9e9b45ce7ac6d7475c69abc4f763ea3195cce10f1cbff65bf9f09c1cf868a libpcrypt-freebsd-x86-64.so
6fd47cc98534065ace055e378746492bbb4b07807d35c8639df9f56f895878cc libpcrypt-linux-arm32.so
4bf2131e82cd95d2a48f6807af42cbe6540238ac417529d9e3d82cac3a28e5d4 libpcrypt-linux-arm64.so
f3110263ac01788edb580e1a96d0bc52a355720298876b4c66d5ce089b0cc7de libpcrypt-linux-i386.so
49d86fcea6d40371c7194acc494b715e06a0733ab28ed4460496629e83d9d01d libpcrypt-linux-x86-64.so
549cbc22d4fdee557706ceb70f10c935e995509b2f230272c6c6384c7eb6f925 libniahash-macos-i386.dylib
bfd97a9028a30e711ac5db7967e425f298ca710b5f3c3878c85ffa47df40da76 libniahash-macos-x86-64.dylib
62d87ca447fac6e9d366119c3974ba5016feaeb6aa886eda4fbc8aa3e85e456d libpcrypt-macos-i386.dylib
def6546280ee3d5117e04856532bd81517424695036d4bb60887c8d06412cd32 libpcrypt-macos-x86-64.dylib
663bec4e8987923c2f82f4aa99c9039c04cf67be6c9eeaec628861ce839c573f libniahash-windows-i686.dll
c0f9197c67a82b0920293b1a8e2c0a74e1125236c0da7c9d53ab6b7d2b72c70f libniahash-windows-x86-64.dll
dbf76869afde7fed4f40118f72e4bfa68ea50c20bc32397921f9a04e1e948c56 libpcrypt-windows-i686.dll
b6d11b185384a5df02a48c064b6005074a90b14dfbec05b8539d2bba987a33cc libpcrypt-windows-x86-64.dll
```

## Documentation
More detailed instructions on how to compile the given libraries will be updated soon, for now a roughy guideline is given below.

* Checkout https://github.com/laverdet/pcrypt-c (Thanks a lot to @marcel)
* Use `make all`
* Checkout https://gist.github.com/Noctem/018c107d6a6297c24e36a00d4da046c9 (Thanks a lot to @Waryas, @marcel, @HatchingEgg, @Apoc)
* Make the file according to the following flags: (Thanks a lot to @noctem)
```
Linux:
cc -fPIC -O3 -shared niahash.c -o libniahash-linux-x86-64.so
macOS:
clang -march=core2 -shared -fPIC -mmacosx-version-min=10.7 -O3 niahash.c -o libniahash-macos-x86-64.dylib
Windows:
x86_64-w64-mingw32-gcc -O3 -fPIC -shared niahash.c -o libniahash-windows-x86-64.dll
```

## Licensing
[MIT](https://github.com/pokelibs/pgoapi-libs/blob/master/LICENSE)

### Third Party Licenses
None

## Contributing
Currently, you can contribute to this project by visiting and discussing with us in Discord
20 changes: 20 additions & 0 deletions pogom/lib/SHA256SUMS
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
b8f62a0fbb301eabbe4cb83bab2c17f35360116b46e196fd53ef5da1d7d1395d libniahash-freebsd-i386.so
3ffbc2f64ffda74c82cefeff94a7d3aeba72efcc890b847ff2732c308768e6dd libniahash-freebsd-x86-64.so
e1eff1af978b0fda2b883d38c53290c15de3ca4274b4bd8690d41eab8558843b libniahash-linux-arm32.so
8fcb0424682df55684410ebb078adc467842f2cf4d2c1b5cc757e461388671df libniahash-linux-arm64.so
c194a4207eabf0f3e2b418e39747dabeb63aba397a73b27c64eb064e9b344d83 libniahash-linux-i386.so
dd1e9510e58f2793f3f92ec352c8d301e797be473c8aa00d731e5d931f0f76b2 libniahash-linux-x86-64.so
c6985404f10dd5daab8458c80432ae773b4ac2d8129fcbd05c25668e199d5882 libpcrypt-freebsd-i386.so
a6f9e9b45ce7ac6d7475c69abc4f763ea3195cce10f1cbff65bf9f09c1cf868a libpcrypt-freebsd-x86-64.so
6fd47cc98534065ace055e378746492bbb4b07807d35c8639df9f56f895878cc libpcrypt-linux-arm32.so
4bf2131e82cd95d2a48f6807af42cbe6540238ac417529d9e3d82cac3a28e5d4 libpcrypt-linux-arm64.so
f3110263ac01788edb580e1a96d0bc52a355720298876b4c66d5ce089b0cc7de libpcrypt-linux-i386.so
49d86fcea6d40371c7194acc494b715e06a0733ab28ed4460496629e83d9d01d libpcrypt-linux-x86-64.so
549cbc22d4fdee557706ceb70f10c935e995509b2f230272c6c6384c7eb6f925 libniahash-macos-i386.dylib
bfd97a9028a30e711ac5db7967e425f298ca710b5f3c3878c85ffa47df40da76 libniahash-macos-x86-64.dylib
62d87ca447fac6e9d366119c3974ba5016feaeb6aa886eda4fbc8aa3e85e456d libpcrypt-macos-i386.dylib
def6546280ee3d5117e04856532bd81517424695036d4bb60887c8d06412cd32 libpcrypt-macos-x86-64.dylib
663bec4e8987923c2f82f4aa99c9039c04cf67be6c9eeaec628861ce839c573f libniahash-windows-i686.dll
c0f9197c67a82b0920293b1a8e2c0a74e1125236c0da7c9d53ab6b7d2b72c70f libniahash-windows-x86-64.dll
dbf76869afde7fed4f40118f72e4bfa68ea50c20bc32397921f9a04e1e948c56 libpcrypt-windows-i686.dll
b6d11b185384a5df02a48c064b6005074a90b14dfbec05b8539d2bba987a33cc libpcrypt-windows-x86-64.dll
2 changes: 2 additions & 0 deletions pogom/lib/checksum.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
sha256sum *.so *.dylib *.dll > SHA256SUMS
Binary file added pogom/lib/libniahash-freebsd-i386.so
Binary file not shown.
Binary file added pogom/lib/libniahash-freebsd-x86-64.so
Binary file not shown.
Binary file added pogom/lib/libniahash-linux-arm32.so
Binary file not shown.
Binary file added pogom/lib/libniahash-linux-arm64.so
Binary file not shown.
Binary file added pogom/lib/libniahash-linux-i386.so
Binary file not shown.
Binary file added pogom/lib/libniahash-linux-x86-64.so
Binary file not shown.
Binary file added pogom/lib/libniahash-macos-i386.dylib
Binary file not shown.
Binary file added pogom/lib/libniahash-macos-x86-64.dylib
Binary file not shown.
Binary file added pogom/lib/libniahash-windows-i686.dll
Binary file not shown.
Binary file added pogom/lib/libniahash-windows-x86-64.dll
Binary file not shown.
Binary file added pogom/lib/libpcrypt-freebsd-i386.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-freebsd-x86-64.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-linux-arm32.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-linux-arm64.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-linux-i386.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-linux-x86-64.so
Binary file not shown.
Binary file added pogom/lib/libpcrypt-macos-i386.dylib
Binary file not shown.
Binary file added pogom/lib/libpcrypt-macos-x86-64.dylib
Binary file not shown.
Binary file added pogom/lib/libpcrypt-windows-i686.dll
Binary file not shown.
Binary file added pogom/lib/libpcrypt-windows-x86-64.dll
Binary file not shown.
Binary file removed pogom/libencrypt/encrypt32bit.dll
Binary file not shown.
Binary file removed pogom/libencrypt/encrypt64bit.dll
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-centos-x86-64.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-freebsd-64.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-freebsd10-64.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-linux-arm-32.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-linux-arm-64.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-linux-x86-32.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-linux-x86-64.so
Binary file not shown.
Binary file removed pogom/libencrypt/libencrypt-osx-64.so
Binary file not shown.
1 change: 1 addition & 0 deletions pogom/pgoapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
__author__ = 'tjado'
__license__ = 'MIT License'
__copyright__ = 'Copyright (c) 2016 tjado <https://github.com/tejado>'
__patchedBy__ = 'Patched for API version 0.51.0 by the PokeHunter Project <https://github.com/PokeHunterProject>'

protobuf_exist = False
protobuf_version = "0"
Expand Down
161 changes: 161 additions & 0 deletions pogom/pgoapi/hash_emulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
from __future__ import print_function
from unicorn import *
from unicorn.arm_const import *

from binascii import hexlify, unhexlify

import struct
import ctypes

DEBUG = 0

# WORK IN PROGRESS : Hash Emulation on unicorn engine
class HashEmulator:
POGO_FILE_NAME = "pokemongo_0_45.payload"

POGO_BIN_SIZE = 0x0327F500
POGO_BIN_OFFSET = 0x00008830
POGO_BIN_MAX = POGO_BIN_SIZE
POGO_FUNC = 0x1B175C0
POGO_FUNC_END = 0x1B17AA4
NL_SYM_PTR_BASE = 0x2CC8000
LA_SYM_PTR_END = 0x2D09E58
POGO_EXP_ADDR = NL_SYM_PTR_BASE
POGO_EXP_CNT = ((LA_SYM_PTR_END - NL_SYM_PTR_BASE) / 4)
POGO_SEG_COMMON = 0x0312C980

POGO_NOP_FIX1 = 0x01B1769C
POGO_NOP_FIX2 = 0x01b17cd4
POGO_HICKUP_ENTRY_BEGIN_STOP = 0x01B175D2
POGO_HICKUP_ENTRY_2 = 0x01B175DA
POGO_HICKUP_ENTRY_2_STOP = 0x01B17CF4
POGO_HICKUP_ENTRY_3 = 0x01B17CFE

def __init__(self):
self.mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)

self.mu.hook_add(UC_HOOK_CODE, self.POGO_hook)
self.mu.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.POGO_hook_mem)

# heap and stack allocation
self.POGO_createmap(0xE0000000, 0x2000)
self.POGO_createmap(0xD0000000, 0x2000)
sp = 0xD0000000 + 0x1000

# stack
self.mu.reg_write(UC_ARM_REG_SP, sp)

# start code calling hash func
self.POGO_createmap(0x1000, 0x1000)
self.mu.mem_write(0x1000, "\x90\x47")

# binary mapping
f = open(self.POGO_FILE_NAME, "rb")
code_buffer = f.read(self.POGO_BIN_SIZE)
f.close()

# memory prepare
self.POGO_createmap(self.POGO_BIN_OFFSET, self.POGO_BIN_MAX - self.POGO_BIN_OFFSET)

code_buffer = code_buffer[:self.POGO_NOP_FIX1] + b'\x00\x00\x00\x00' + code_buffer[self.POGO_NOP_FIX1+4:]
code_buffer = code_buffer[:self.POGO_NOP_FIX2] + b'\x00\x00\x00\x00' + code_buffer[self.POGO_NOP_FIX2+4:]

# all segment
self.mu.mem_write(self.POGO_BIN_OFFSET, code_buffer[self.POGO_BIN_OFFSET:self.POGO_BIN_MAX])

# export address fill with any valid address
exportdata = self.POGO_SEG_COMMON
exportaddr = self.POGO_EXP_ADDR

for i in range(0, self.POGO_EXP_CNT):
value1 = code_buffer[exportaddr + (i*4)].encode("hex")
value2 = code_buffer[exportaddr + (i*4)+1].encode("hex")
value3 = code_buffer[exportaddr + (i*4)+2].encode("hex")
value4 = code_buffer[exportaddr + (i*4)+3].encode("hex")
if value1 == "00" and value2 == "00" and value3 == "00" and value4 == "00":
self.mu.mem_write(exportaddr + (i * 4), struct.pack("<q", exportdata))

def POGO_hook(self, uc, address, size, user_data):
if (DEBUG):
print(">>> Tracing instruction at 0x%x" %(address), end=' ')
#for i in range(0, 2):
#print(code_buffer[address + i].encode("hex"), end=' ')
print(" ")

def POGO_hook_mem(self, uc, access, addr, size, value, user_data):
if DEBUG and addr < 0xD0000000:
if access == UC_MEM_READ:
print("r", end=' ')
elif access == UC_MEM_WRITE:
print("w", end=' ')
elif access == UC_MEM_FETCH:
print("f", end=' ')
print("len:%d at 0x%lx" % (size, addr))

def POGO_createmap(self, address, size):
chunk = address % 0x1000
taddr = address - chunk
tsize = ((0xFFF + chunk + size) / 0x1000) * 0x1000

self.mu.mem_map(taddr, tsize)

def push(self, reg):
sp = self.mu.reg_read(UC_ARM_REG_SP)
regVal = self.mu.reg_read(reg)
self.mu.mem_write(sp, struct.pack(">i", regVal))
sp = sp - 4
self.mu.reg_write(UC_ARM_REG_SP, sp)

def pop(self, reg):
sp = self.mu.reg_read(UC_ARM_REG_SP)
regVal = self.mu.mem_read(sp, 4)
self.mu.reg_write(reg, struct.unpack("i", regVal)[0])
sp = sp + 4
self.mu.reg_write(UC_ARM_REG_SP, sp)

def hash(self, buffer, size):
# HASH
#buffer = "\x46\xe9\x45\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
buffer = "\x46\xe9\x45\xf8" + "\x00" * 24
print(hexlify(buffer))
print(size)
#size = 28

self.mu.reg_write(UC_ARM_REG_R0, 0xE0001000)
self.mu.reg_write(UC_ARM_REG_R1, size)
self.mu.reg_write(UC_ARM_REG_R2, self.POGO_FUNC + 1)

self.mu.mem_write(0xE0001000, buffer)

try:
self.mu.emu_start(0x1000, self.POGO_HICKUP_ENTRY_BEGIN_STOP)
print("1 done")
self.push(UC_ARM_REG_D8)
self.push(UC_ARM_REG_D9)
self.push(UC_ARM_REG_D10)
self.push(UC_ARM_REG_D11)
self.push(UC_ARM_REG_D12)
self.push(UC_ARM_REG_D13)
self.push(UC_ARM_REG_D14)
self.push(UC_ARM_REG_D15)
self.mu.emu_start(self.POGO_HICKUP_ENTRY_2, self.POGO_HICKUP_ENTRY_2_STOP)
print("2 done")
self.pop(UC_ARM_REG_D15)
self.pop(UC_ARM_REG_D14)
self.pop(UC_ARM_REG_D13)
self.pop(UC_ARM_REG_D12)
self.pop(UC_ARM_REG_D11)
self.pop(UC_ARM_REG_D10)
self.pop(UC_ARM_REG_D9)
self.pop(UC_ARM_REG_D8)
self.mu.emu_start(self.POGO_HICKUP_ENTRY_3, 0x1002)
print("3 done")
except UcError as e:
print("ERROR: %s" % e)

r0 = self.mu.reg_read(UC_ARM_REG_R0)
r1 = self.mu.reg_read(UC_ARM_REG_R1)

ret = r1
ret = (ret << 32) | r0
return ret
15 changes: 15 additions & 0 deletions pogom/pgoapi/hash_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class HashEngine:
def __init__(self):
self.location_hash = None
self.location_auth_hash = None
self.request_hashes = []

def hash(self, timestamp, latitude, longitude, altitude, authticket, sessiondata, requests):
raise NotImplementedError()

def get_location_hash(self):
return self.location_hash
def get_location_auth_hash(self):
return self.location_auth_hash
def get_request_hashes(self):
return self.request_hashes
55 changes: 55 additions & 0 deletions pogom/pgoapi/hash_library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from __future__ import absolute_import

import ctypes
import struct

from .hash_engine import HashEngine
from .utilities import d2h

HASH_SEED = 0x46E945F8 # static hash seed from app

class HashLibrary(HashEngine):
def __init__(self, library_path):
self._hash_lib = ctypes.cdll.LoadLibrary(library_path)
self._hash_lib.compute_hash.argtypes = (ctypes.POINTER(ctypes.c_ubyte), ctypes.c_uint32)
self._hash_lib.compute_hash.restype = ctypes.c_uint64

def hash(self, timestamp, latitude, longitude, altitude, authticket, sessiondata, requests):
self.location_hash = None
self.location_auth_hash = None
self.request_hashes = []

first_hash = self.hash32(authticket, seed=HASH_SEED)
location_bytes = d2h(latitude) + d2h(longitude) + d2h(altitude)
loc_hash = self.hash32(location_bytes, seed=first_hash)
self.location_auth_hash = ctypes.c_int32(loc_hash).value

loc_hash = self.hash32(location_bytes, seed=HASH_SEED)
self.location_hash = ctypes.c_int32(loc_hash).value

first_hash = self.hash64salt32(authticket, seed=HASH_SEED)
for request in requests:
req_hash = self.hash64salt64(request.SerializeToString(), seed=first_hash)
self.request_hashes.append(ctypes.c_int64(req_hash).value)

def hash64salt32(self, buf, seed):
buf = struct.pack(">I", seed) + buf
return self.call_hash(buf)

def hash64salt64(self, buf, seed):
buf = struct.pack(">Q", seed) + buf
return self.call_hash(buf)

def hash32(self, buf, seed):
buf = struct.pack(">I", seed) + buf
hash64 = self.call_hash(buf)
signedhash64 = ctypes.c_int64(hash64)
return ctypes.c_uint(signedhash64.value).value ^ ctypes.c_uint(signedhash64.value >> 32).value

def call_hash(self, buf):
buf = list(bytearray(buf))
num_bytes = len(buf)
array_type = ctypes.c_ubyte * num_bytes

data = self._hash_lib.compute_hash(array_type(*buf), ctypes.c_uint32(num_bytes))
return ctypes.c_uint64(data).value
Loading