弁財天

ゴフマン「専門家を信じるのではなく、自分自身で考えて判断せよ」

JavaのJNIコードのWideCharToMultiByte処理をサルベージ。

プロジェクトに対するサボタージュ工作が日常茶飯事になってきた。 まぁ臓器狩りのために人さらいして殺人したり、フィリピンで自動車税を使ってマネロンしたり、人間のクズみたいなやつらを相手にしてるので、そんなことはよく起きることなのだw。

なんと!、今回は意図的にソースコードのファイルを削除してしまう嫌がらせにあっている。 どうせどこかに隠し持っているのだろうが、ソースコードを渡さないという自治体の作戦なのだw。 しかもそれがないとサブシステムの一部が動作しないのであるw。 だれかの腎臓を差し出すと見つけてくれるのかすら?

しょーがないなー。

なので、Hex-Rays decompilerで.DLLからC言語のコードの復元を試みている。 破壊されたのはJavaのJNIで呼び出されるDLLのソースコードなのだw。

Hex-Rayで復元できたサボタージュ工作にあった問題のJNIで呼び出されるDLLのソースコードの一部はこんなかんじw。

//----- (10001000) --------------------------------------------------------
//signed int __stdcall Java_txd_HogeTuxedo_hogeTrStart(LPCWSTR lpWideCharStr, int a2, int a3, int a4) //@@@
JNIEXPORT jint JNICALL Java_txd_HogeTuxedo_hogeTrStart(JNIEnv *lpWideCharStr, jclass a2, jstring a3, jstring a4)
{
  void *v4; // edi@1
  signed int result; // eax@2
  void *v6; // eax@3
  const CHAR *v7; // esi@3
  char v8; // al@4
  int v9; // ebx@5

  v4 = sub_10001440(lpWideCharStr, a3);//JNIENVとa3(何やら4文字のアプリケーションコードw)
  if ( v4 )
  {
    v6 = sub_10001440(lpWideCharStr, a4);//JNIENVとa4(ログディレクトリ文字列なのだとかw)
    v7 = (const CHAR *)v6;
    if ( v6 )
    {
      v8 = toupper(*(_BYTE *)v6);
      _chdrive(v8 - 64);//chdirして
      _chdir(v7);//chdirしてるw。なんだこれ。
    }
    v9 = HGQNAC_TrStart(v4);
    free(v4);
    free((void *)v7);
    result = v9;
  }
  else
  {
    result = -99;
  }
  return result;
}
// 100014C0: using guessed type int __stdcall HGQNAC_TrStart(_DWORD);

Visual Studio 2015でコンパイルして、DLLをビルドw、配置してTomcat/Javaから呼び出すと JavaVMのプロセスごと落ちてしまったw。まぁ当たり前か。

Javaのスレッドダンプを見る限り、復元し損なったプライベート関数で落ちてるよーだw。

//----- (10001440) --------------------------------------------------------
void *__cdecl sub_10001440(LPCWSTR lpWideCharStr, int a2)
{
  void *result; // eax@2
  LPCWSTR v3; // esi@3
  int v4; // eax@3
  int v5; // ebx@3
  void *v6; // eax@5
  void *v7; // edi@5
  const WCHAR *lpWideCharStra; // [sp+14h] [bp+4h]@3

  if ( a2 )
  {
    v3 = lpWideCharStr;
    lpWideCharStra = (const WCHAR *)(*(int (__stdcall **)(LPCWSTR, int, _DWORD))(*(_DWORD *)lpWideCharStr + 660))(
                                      lpWideCharStr,
                                      a2,
                                      0);
    v4 = (*(int (__stdcall **)(LPCWSTR, int))(*(_DWORD *)v3 + 656))(v3, a2);
    v5 = v4;
    if ( v4 )
    {
      v6 = malloc(2 * v4 + 1);
      v7 = v6;
      *((_BYTE *)v6 + WideCharToMultiByte(0, 0, lpWideCharStra, v5, (LPSTR)v6, 2 * v5 + 1, 0, 0)) = 0;
      (*(void (__stdcall **)(LPCWSTR, int, const WCHAR *))(*(_DWORD *)v3 + 664))(v3, a2, lpWideCharStra);
      result = v7;
    }
    else
    {
      result = &unk_10007CF0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

WideCharToMultiByteを呼んでいるので、元のソースコードはJava内部のUTF-16との文字コード変換の処理だったのだと思う。

みっちーわーるどw→JNI サンプル(戻り値に文字列の配列を返すJNIサンプル)
困ったときの中国人w→jni和C++通信中文乱码的问题

たぶんコードはこれだw。

char * JStringToWindows(JNIEnv * pJNIEnv, jstring jstr)
{
    jsize len = pJNIEnv->GetStringLength(jstr);
    const jchar * jcstr = pJNIEnv->GetStringChars(jstr, NULL);
    int size = 0;
    char * str = (char *)malloc(len * 2 + 1);
    if ((size = WideCharToMultiByte(CP_ACP, 0, LPCWSTR(jcstr), len, str, len * 2 + 1, NULL, NULL)) == 0)
        return NULL;
    pJNIEnv->ReleaseStringChars(jstr, jcstr);
    str[size] = 0;
    return str;
}
jstring WindowsTojstring( JNIEnv* env, char* str )
{
    jstring rtn = 0;
    int slen = strlen(str);
    unsigned short * buffer = 0;
    if( slen == 0 )
        rtn = (env)->NewStringUTF(str ); 
    else
    {
        int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
        buffer = (unsigned short *)malloc( length*2 + 1 );
        if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
            rtn = (env)->NewString(  (jchar*)buffer, length );
    }
    if( buffer )
        free( buffer );
    return rtn;
}

投稿されたコメント:

コメント
コメントは無効になっています。