RandXor128 monster strike

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

RandXor128 monster strike

Post by chrrox »

How would you handle this in quickbms.
game uses this for encryption
android game monster-strike-20.0.1
#include <cstdint>
#include <random>
#include <limits>
class RandXor128
{
private:
std::uint_fast32_t x{ 123456789 }, y{ 362436069 }, z{ 521288629 }, w{ 88675123 };
public:
//通常の乱数
constexpr std::uint_fast32_t operator()() noexcept {
const std::uint_fast32_t t{ (x ^ (x << 11)) };
x = y; y = z; z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
//0~最大値-1 (余りの範囲の一様分布乱数)
constexpr std::uint_fast32_t operator()(const std::uint_fast32_t max_) noexcept {
return ((std::uint_fast32_t)(((double)operator()() / ((double)(std::numeric_limits<std::uint_fast32_t>::max)() + 1)) * max_));
}
//最小値~最大値
constexpr std::uint_fast32_t operator()(const std::uint_fast32_t min_, const std::uint_fast32_t max_) noexcept {
return ((std::uint_fast32_t)(((double)operator()() / ((double)(std::numeric_limits<std::uint_fast32_t>::max)() + 1)) * (max_ - min_ + 1)) + min_);
}

constexpr void setSeed(const std::uint_fast32_t x_, const std::uint_fast32_t y_, const std::uint_fast32_t z_, const std::uint_fast32_t w_) noexcept {
x = x_;
y = y_;
z = z_;
w = w_;
}

};

2.5mb of the xor key generated attached.

the initial vectors should be

Code: Select all

 sn::RandXor128::Seed::Seed((sn::RandXor128::Seed *)&v3, 0x1F123BB5u, 0x75BCD15u, 0x5491333u, 0x159A55E5u);


Code: Select all

int *__fastcall sn::RandXor128::setSeed(int *result, int a2, int a3, int a4, int a5)
{
  int v5; // r4
  int v6; // r5
  int v7; // r12
  __int64 v8; // r4

  v5 = 0;
  v6 = 0;
  if ( !a3 )
    v5 = 1;
  if ( !a2 )
    v6 = 1;
  v7 = a5;
  LODWORD(v8) = v5 | v6 | (a4 == 0);
  HIDWORD(v8) = a5 == 0;
  if ( v8 )
  {
    a4 = 521288629;
    a2 = 123456789;
    v7 = 88675123;
    a3 = 362436069;
  }
  *result = a2;
  result[1] = a3;
  result[2] = a4;
  result[3] = v7;
  result[4] = 0;
  return result;
}
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: RandXor128 monster strike

Post by aluigi »

When in doubt, use tcc ;)

Code: Select all

set MEMORY_FILE10 string "
typedef unsigned int u32;
u32 x=123456789, y=362436069, z=521288629, w=88675123;
u32 RandXor128(void) {
    u32 t = (x ^ (x << 11));
    x = y; y = z; z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
void seed(u32 x_, u32 y_, u32 z_, u32 w_) {
    x = x_;
    y = y_;
    z = z_;
    w = w_;
}
void decrypt(unsigned char *buff, int size, u32 x_, u32 y_, u32 z_, u32 w_) {
    int i;
    seed(x_, y_, z_, w_);
    for(i = 0; i < size; i++) {
        buff[i] ^= RandXor128();
    }
}
"

get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 decrypt tcc RET MEMORY_FILE SIZE 0x1F123BB5 0x75BCD15 0x5491333 0x159A55E5
log "dump.dat" 0 SIZE MEMORY_FILE


A little note: constant number must not have characters at their end or they will be wrongly intepreted by quickbms so 0x1F123BB5 is ok while 0x1F123BB5u is bad.