Android逆向練習(xí)(三)Ericky編寫的“簡單”crackme

Ericky大牛的一個無反調(diào)試CrackMe(Java_by_Ericky_crackme01_JNI_EatRice)酪劫,非常適合用來練手,姑且先試試铅乡。
鏈接: https://pan.baidu.com/s/1hr9db96 密碼: ntet
拿到app后先反編譯,到RegActivity看到注冊button,然后繼續(xù)跟蹤setOnClickListener


如果不為空切長度不為0搔耕,則調(diào)用JIN的native的靜態(tài)方法EatRice,傳參為string(注冊碼),int(注冊碼長度)

public class JNI
{
  static
  {
    System.loadLibrary("xy");
  }
  
  public static native boolean EatRice(String paramString, int paramInt);
}

之前沒接觸過so逆向弃榨,只能跟著前輩們一點(diǎn)一點(diǎn)的學(xué)習(xí)菩收。最初使用的是Hopper,乍看起來在反編譯和結(jié)構(gòu)上都可以鲸睛,但是看到偽代碼就知道差了很多娜饵,參數(shù)都沒有,也不知道怎么修正官辈。只能想辦法轉(zhuǎn)IDA了箱舞。。拳亿。

在mac上搞不到能用的IDA晴股,所以只能搭上虛擬機(jī),我這里使用的是Parallels Desktop12版本肺魁。安裝win7鏡像电湘,就能正常使用windows系統(tǒng)啦。
打開IDA万搔,加載libxy.so

加載完成后胡桨,找到Java_by_Ericky_crackme01_JNI_EatRice


fn + F5看看代碼是什么樣

image.png

在IDA view里上下翻翻明顯代碼應(yīng)該多好多才對,這就是傳說的IDA識別問題瞬雹,需要手動修一下昧谊。空格切換到Graph view酗捌,看到連個分叉呢诬,左邊的明顯是入口,然后往下查看胖缤,發(fā)現(xiàn)是箭頭指的位置有識別問題尚镰。


定位到這里,點(diǎn)擊任意指令哪廓,然后Remove function tail

Edit->Functions->Remove function tail

然后Force BL call

Edit->others->Force BL call

修復(fù)后的看起來就正常了



fn + F5看一下代碼狗唉,比之前正常的多了
接下來還得處理一下結(jié)構(gòu)體識別,就是說的導(dǎo)入JNI.h頭文件涡真。我這里怎么試都會報(bào)錯分俯,試過了注釋stdarg.h,改掉#define JNIIMPORT哆料,也更改了complier 目錄缸剪,但就是不行,還是會報(bào)錯东亦。google一下也沒能解決杏节,感覺可能跟使用的環(huán)境有關(guān)(mac上運(yùn)行win虛擬機(jī))。無奈之下只好手動fix。
切換到Structures奋渔,添加standard structure:不知道沒有導(dǎo)入.h文件镊逝,這個有什么作用

Edit -> Add struct type->Add standard structure

手動修正第一個參數(shù)為JNIEnv*類型,修改第一個變量為env卒稳。點(diǎn)擊參數(shù)按y鍵進(jìn)行修改蹋半。這里面第二個參數(shù)是干什么的我還沒弄清楚他巨,看別人說是因?yàn)殪o態(tài)方法充坑,因此第二個參數(shù)暫時不用管。在反編譯代碼中也確實(shí)沒看到第二個參數(shù)的使用染突,這個問題后面再研究一下捻爷。第三個就是注冊碼,第四個是注冊碼的長度份企。然后在修正一些變量名字也榄,改成容易識別的,修正后的結(jié)果:

int __fastcall Java_by_Ericky_crackme01_JNI_EatRice(JNIEnv *env, int a2, jstring regString, jint regLenght)
{
  jint lenght_regCode; // r4@1
  signed int v5; // r6@1
  _BYTE *byte_regCode; // r5@1
  char v7; // r3@4
  unsigned __int8 v8; // r2@4
  signed int v9; // r5@4
  signed int v10; // r7@4
  unsigned __int8 v11; // r6@9
  signed int v12; // r4@9
  signed int v13; // r5@9
  signed int v14; // r7@12
  unsigned __int8 v15; // r3@14
  signed int i; // r5@14
  unsigned int v17; // r6@16
  int v18; // r4@22
  signed int v19; // r7@22
  int v20; // r5@24
  unsigned int v21; // r4@24
  signed int v22; // r5@26
  int v23; // r0@27
  int v24; // r0@27
  signed int v26; // r4@33
  signed int v27; // r3@35
  int v28; // r3@37
  signed int v29; // r2@37
  char v30; // [sp+0h] [bp-28h]@22
  signed int v31; // [sp+4h] [bp-24h]@7
  _BYTE *v32; // [sp+8h] [bp-20h]@4
  _BYTE *temp_byte_code; // [sp+10h] [bp-18h]@4

  lenght_regCode = regLenght;
  v5 = 0;
  byte_4004 = 0;
  byte_4008 = 0;
  byte_400C = 0;
  byte_4010 = 0;
  byte_regCode = string_to_byte(env, regString);
  if ( *byte_regCode != 88 || byte_regCode[1] != 35 || lenght_regCode != 7 )
  {
    j_j_sleep(3u);
    return 0;
  }
  temp_byte_code = j_j_malloc(1u);
  v7 = 35;
  *temp_byte_code = 35;
  v8 = byte_regCode[2];
  v32 = byte_regCode;
  temp_byte_code[1] = v8;
  v9 = -1;
  v10 = 63689;
  while ( 1 )
  {
    v5 = (unsigned __int8)v7 + v5 * v10;
    if ( v9 == -2 )
      break;
    v10 *= 378551;
    v7 = temp_byte_code[-v9--];
  }
  v31 = 1;
  if ( ((v5 + (v5 >> 31)) ^ (v5 >> 31)) == 2020122470 )
    byte_4004 = 1;
  *temp_byte_code = v8;
  v11 = v32[3];
  temp_byte_code[1] = v11;
  v12 = -1;
  v13 = 1315423911;
  while ( 1 )
  {
    v13 ^= ((unsigned int)v13 >> 2) + 32 * v13 + v8;
    if ( v12 == -2 )
      break;
    v8 = temp_byte_code[-v12--];
  }
  v14 = 0;
  if ( ((v13 + (v13 >> 31)) ^ (v13 >> 31)) == 1532463978 )
    byte_4008 = 1;
  *temp_byte_code = v11;
  v15 = v32[4];
  temp_byte_code[1] = v15;
  for ( i = -1; ; --i )
  {
    v17 = v11 + 16 * v14;
    v14 = v17 & 0xF0000000 ? ((v17 & 0xF0000000) >> 24) ^ v17 & 0xFFFFFFF : v17;
    if ( i == -2 )
      break;
    v11 = temp_byte_code[-i];
  }
  if ( ((v14 + (v14 >> 31)) ^ (v14 >> 31)) == 728 )
    byte_400C = 1;
  *temp_byte_code = v15;
  v30 = v32[5];
  temp_byte_code[1] = v30;
  v18 = 0;
  v19 = -1;
  while ( 1 )
  {
    v20 = v15 + v18;
    v21 = v15 + v18;
    if ( v20 & 0xF0000000 )
      v21 = ((v20 & 0xF0000000) >> 24) ^ v20;
    v22 = ((v20 | 0xFFFFFFF) ^ 0xF0000000) & v21;
    if ( v19 == -2 )
      break;
    v15 = temp_byte_code[-v19--];
    v18 = 16 * v21;
  }
  *temp_byte_code = v30;
  temp_byte_code[1] = v32[6];
  v23 = sub_1238(temp_byte_code, 2);
  v24 = (v23 + (v23 >> 31)) ^ (v23 >> 31);
  if ( ((v22 + (v22 >> 31)) ^ (v22 >> 31)) == 960 && v24 == 789320428 )
  {
    byte_4010 = 1;
LABEL_32:
    v31 = 0;
    goto LABEL_33;
  }
  if ( byte_4010 )
    goto LABEL_32;
LABEL_33:
  v26 = 1;
  if ( byte_4008 )
    v26 = 0;
  v27 = 1;
  if ( byte_4004 )
    v27 = 0;
  v28 = v27 | v26;
  v29 = 1;
  if ( byte_400C )
    v29 = 0;
  return ~(v28 | v29 | v31) & 1;
}

然后慢慢讀代碼司志,注冊碼長度甜紫,然后四個變量初始化為0,接著調(diào)用sub_10C4()

  lenght_regCode = a4;
  v5 = 0;
  byte_4004 = 0;
  byte_4008 = 0;
  byte_400C = 0;
  byte_4010 = 0;
  v6 = sub_10C4(a1, a3);

雙擊進(jìn)入sub_10C4()骂远,同樣修正參數(shù)

_BYTE *__fastcall sub_10C4(JNIEnv *env, jstring regCode)
{
  jstring vRegCode; // ST08_4@1
  JNIEnv *vEnv; // r4@1
  int v4; // ST04_4@1
  int v5; // r7@1
  int v6; // r0@1
  int v7; // r5@1
  int v8; // r7@1
  _BYTE *v9; // r6@1
  int v11; // [sp+8h] [bp-18h]@1

  vRegCode = regCode;
  vEnv = env;
  v4 = ((int (*)(void))(*env)->FindClass)();
  v5 = ((int (__fastcall *)(JNIEnv *, const char *))(*vEnv)->NewStringUTF)(vEnv, "utf-8");
  v6 = ((int (__fastcall *)(JNIEnv *, int, const char *, const char *))(*vEnv)->GetMethodID)(
         vEnv,
         v4,
         "getBytes",
         "(Ljava/lang/String;)[B");
  v7 = sub_12AC(vEnv, vRegCode, v6, v5);
  v8 = ((int (__fastcall *)(JNIEnv *, int))(*vEnv)->GetArrayLength)(vEnv, v7);
  v9 = 0;
  v11 = ((int (__fastcall *)(JNIEnv *, int, _DWORD))(*vEnv)->GetByteArrayElements)(vEnv, v7, 0);
  if ( v8 >= 1 )
  {
    v9 = j_j_malloc(v8 + 1);
    j_j___aeabi_memcpy();
    v9[v8] = 0;
  }
  ((void (__fastcall *)(JNIEnv *, int, int, _DWORD))(*vEnv)->ReleaseByteArrayElements)(vEnv, v7, v11, 0);
  return v9;
}

每個函數(shù)都點(diǎn)下


_BYTE *__fastcall sub_10C4(JNIEnv *env, jstring a2)
{
  jstring v2; // ST08_4@1
  JNIEnv *v3; // r4@1
  jclass v4; // ST04_4@1
  jstring v5; // r7@1
  jmethodID v6; // r0@1
  void *v7; // r5@1
  jsize v8; // r7@1
  _BYTE *v9; // r6@1
  jbyte *v11; // [sp+8h] [bp-18h]@1

  v2 = a2;
  v3 = env;
  v4 = (*env)->FindClass(env, "java/lang/String");
  v5 = (*v3)->NewStringUTF(v3, "utf-8");
  v6 = (*v3)->GetMethodID(v3, v4, "getBytes", "(Ljava/lang/String;)[B");
  v7 = (void *)sub_12AC((int)v3, (int)v2, (int)v6, (int)v5);
  v8 = (*v3)->GetArrayLength(v3, v7);
  v9 = 0;
  v11 = (*v3)->GetByteArrayElements(v3, v7, 0);
  if ( v8 >= 1 )
  {
    v9 = j_j_malloc(v8 + 1);
    j_j___aeabi_memcpy();
    v9[v8] = 0;
  }
  (*v3)->ReleaseByteArrayElements(v3, v7, v11, 0);
  return v9;
}

分析過后得知sub_10C4函數(shù)是將String類型的字符串轉(zhuǎn)為byte類型囚霸,然后重新進(jìn)行取值返回。
然后繼續(xù)看代碼激才,這里很明顯有個判斷邏輯拓型,注冊碼第一位byte = 88,第二位byte = 35瘸恼,注冊碼長度=7劣挫,都滿足才能繼續(xù)往后面走。

  if ( *byte_regCode != 88 || byte_regCode[1] != 35 || lenght_regCode != 7 )
  {
    j_j_sleep(3u);
    return 0;
  }

所以前兩位很容易就得到了东帅,打開Sublime新建個.cpp压固,然后build system改成c++ Single File,寫完后command + B直接運(yùn)行靠闭。結(jié)果分別是“X”和"#"

#include <iostream> 
using namespace std;

void funcregCode_1()
{
    int i = 88;
    cout << "1th is : " << (char)i << "    i = " << i <<endl;
}

void funcregCode_2()
{
    int i = 35;
    cout << "2th is : " << (char)i << "    i = " << i <<endl;
}

int main(int argc, char* argv[])
{
    funcregCode_1();
    funcregCode_2();
}
// 運(yùn)行結(jié)果
// 1th is : X    i = 88
// 2th is : #    i = 35

第三位代碼修正

  temp_byte_code = j_j_malloc(1u);
  v7 = 35;
  *temp_byte_code = 35;
  v8 = byte_regCode[2];
  v32 = byte_regCode;
  temp_byte_code[1] = v8;
  v9 = -1;
  v10 = 63689;
  while ( 1 )
  {
    v5 = (unsigned __int8)v7 + v5 * v10;
    if ( v9 == -2 )
      break;
    v10 *= 378551;
    v7 = temp_byte_code[-v9--];
  }
  v31 = 1;
  if ( ((v5 + (v5 >> 31)) ^ (v5 >> 31)) == 2020122470 )
    byte_4004 = 1;

計(jì)算第三位注冊碼:

void funcregCode_3()
{
    for(int i = 0; i < 0xff; i++)
    {
        // v9 = -1;
        int v5 = 0;
        int v7 = 35;
        int v10 = 63689;

        v5 = v7 + v5 * v10;
        v10 *= 378551;
        v7 = i;
        v5 = v7 + v5 * v10;

        if ( ((v5 + (v5 >> 31)) ^ (v5 >> 31)) == 2020122470 )
            cout << "3th is : " << (char)i << "    i = " << i <<endl;
    }
}

// 運(yùn)行結(jié)果
// 3th is : y    i = 121

第四位代碼修正:

 *temp_byte_code = v8;
  v11 = v32[3];
  temp_byte_code[1] = v11;
  v12 = -1;
  v13 = 1315423911;
  while ( 1 )
  {
    v13 ^= ((unsigned int)v13 >> 2) + 32 * v13 + v8;
    if ( v12 == -2 )
      break;
    v8 = temp_byte_code[-v12--];
  }
  v14 = 0;
  if ( ((v13 + (v13 >> 31)) ^ (v13 >> 31)) == 1532463978 )
    byte_4008 = 1;

計(jì)算第四位注冊碼:

void funcregCode_4()
{
    for(int i = 0; i < 0xff; i++)
    {
        int v12 = -1;
        signed int v13 = 1315423911;
        unsigned int v8 = 121;

        v13 ^= ((unsigned int)v13 >> 2) + 32 * v13 + v8;
        v8 = i;
        v13 ^= ((unsigned int)v13 >> 2) + 32 * v13 + v8;

        if ( ((v13 + (v13 >> 31)) ^ (v13 >> 31)) == 1532463978 )
            cout << "4th is : " << (char)i << "    i = " << i << endl;  
    }
}

// 運(yùn)行結(jié)果
// 4th is : *    i = 42

第五位注冊碼修正:

 *temp_byte_code = v11;
  v15 = v32[4];
  temp_byte_code[1] = v15;
  for ( i = -1; ; --i )
  {
    v17 = v11 + 16 * v14;
    v14 = v17 & 0xF0000000 ? ((v17 & 0xF0000000) >> 24) ^ v17 & 0xFFFFFFF : v17;
    if ( i == -2 )
      break;
    v11 = temp_byte_code[-i];
  }
  if ( ((v14 + (v14 >> 31)) ^ (v14 >> 31)) == 728 )
    byte_400C = 1;

計(jì)算第五位注冊碼:

void funcregCode_5()
{
    for(unsigned int i = 0; i < 128; i++)
    {
        signed int v14 = 0;
        unsigned int v17;
        unsigned int v11 = 42;
        for(unsigned int j = -1; ; --j)
        {
            v17 = v11 + 16 * v14;
            v14 = v17 & 0xF0000000 ? ((v17 & 0xF0000000) >> 24) ^ (v17 & 0xFFFFFFF) : v17;
            if (j == -2)
                break;
            v11 = i;
        }
        if ( ((v14 + (v14 >> 31)) ^ (v14 >> 31)) == 728 ){
            cout << "5th is : " << (char)i << "    i = " << i <<endl;
            break;
        }
    }
}
// 運(yùn)行結(jié)果
// 5th is : 8    i = 56

第六位和第七位注冊碼修正:

  *temp_byte_code = v15;
  v30 = v32[5];
  temp_byte_code[1] = v30;
  v18 = 0;
  v19 = -1;
  while ( 1 )
  {
    v20 = v15 + v18;
    v21 = v15 + v18;
    if ( v20 & 0xF0000000 )
      v21 = ((v20 & 0xF0000000) >> 24) ^ v20;
    v22 = ((v20 | 0xFFFFFFF) ^ 0xF0000000) & v21;
    if ( v19 == -2 )
      break;
    v15 = temp_byte_code[-v19--];
    v18 = 16 * v21;
  }
  *temp_byte_code = v30;
  temp_byte_code[1] = v32[6];
  v23 = sub_1238(temp_byte_code, 2);
  v24 = (v23 + (v23 >> 31)) ^ (v23 >> 31);
  if ( ((v22 + (v22 >> 31)) ^ (v22 >> 31)) == 960 && v24 == 789320428 )
  {
    byte_4010 = 1;

這里有個sub_1238帐我,傳第六位注冊碼(byte)和2(int),跟進(jìn)去看看阎毅,里面并不復(fù)雜焚刚。

int __fastcall sub_1238(_BYTE *a1, int a2)
{
  int v2; // r7@1
  int v3; // r3@1
  int v4; // r4@1
  int v5; // r2@1
  unsigned int v6; // r6@2

  v2 = 0;
  v3 = 0;
  v4 = 0;
  v5 = 0;
  while ( a2 )
  {
    v6 = *a1;
    v4 += (v6 >> 2) * v4 * v6 + 804604770;
    v2 += 32 * v6 * v2 * v6 + 1491913760;
    v3 = v3 + 8 * v6 * v3 * v6 - 1774596542;
    v5 = v5 + 2 * v6 * v5 * v6 - 1263339326;
    --a2;
    ++a1;
  }
  return v4 + v5 + v3 + v2;
}

回到外面,這里的v22和v24糾纏了我好久扇调,走進(jìn)了互相帶入的死胡同矿咕。自己解決無果,網(wǎng)上查詢大牛的思路,發(fā)現(xiàn)居然可以拆開第六位和第七位碳柱,分開計(jì)算捡絮。因?yàn)檫@句判斷中有兩個判斷,可以把前面當(dāng)成第六位的驗(yàn)證莲镣,后面的v24用作第七位的驗(yàn)證福稳,這下就容易解決了。

if ( ((v22 + (v22 >> 31)) ^ (v22 >> 31)) == 960 && v24 == 789320428 )

拆分計(jì)算第六位注冊碼:

void funcregCode_6()
{
    signed int v22;
    for(int i = 0; i < 128; i++)
    {
        int v18 = 0;
        signed int v19 = -1;
        unsigned int v15 = 56;

        while(1)
        {
            int v20 = v15 + v18;
            unsigned int v21 = v15 + v18;

            if ( v20 & 0xF0000000 )
                v21 = ((v20 & 0xF0000000) >> 24) ^ v20;
            v22 = ((v20 | 0xFFFFFFF) ^ 0xF0000000) & v21;
            if ( v19 == -2 )
                break;
            v15 = i;
            v18 = 16 * v21;
            v19--;
        }

        if ( ((v22 + (v22 >> 31)) ^ (v22 >> 31)) == 960)
        {
            cout << "6th is : " << (char)i << "    i = " << i <<endl;
            break;
        }
    }
}
// 運(yùn)行結(jié)果
// 6th is : @    i = 64

拆分計(jì)算第七位注冊碼:

void funcregCode_7()
{
    int a2, v2, v3, v4, v5;
    int v23, v24;
    unsigned int v6;
    for(unsigned int i = 0; i < 128; i++)
    {
        v2 = 0;
        v3 = 0;
        v4 = 0;
        v5 = 0;
        a2 = 2;

        v6 = 64;
        v4 += (v6 >> 2) * v4 * v6 + 804604770;
        v2 += 32 * v6 * v2 * v6 + 1491913760;
        v3 = v3 + 8 * v6 * v3 * v6 - 1774596542;
        v5 = v5 + 2 * v6 * v5 * v6 - 1263339326;

        v6 = i;
        v4 += (v6 >> 2) * v4 * v6 + 804604770;
        v2 += 32 * v6 * v2 * v6 + 1491913760;
        v3 = v3 + 8 * v6 * v3 * v6 - 1774596542;
        v5 = v5 + 2 * v6 * v5 * v6 - 1263339326;

        v23 = v4 + v5 + v3 + v2;
        v24 = (v23 + (v23 >> 31)) ^ (v23 >> 31);

        if ( v24 == 0x2F0C12EC )
        {
            cout << "7th is : " << (char)i << "    i = " << i <<endl;
            break;
        }
    }
}
// 運(yùn)行結(jié)果
// 7th is : L    i = 76

所以最終的七位注冊碼就是

X#y*8@L    

總結(jié):
第一次接觸so的反編譯瑞侮,總得來說對我這樣剛接觸的還是挺難的的圆,但過程很有意思,雖然是個簡單的分析半火,但也整整花了2天時間越妈,并且還不是所有地方都能100%說出為什么。過程:
1钮糖、在mac上弄虛擬機(jī)裝win7系統(tǒng) --- Parallels Desktop
2梅掠、手動修復(fù)IDA識別錯誤 --- Remove function tail && Force BL call
3、導(dǎo)入JNI.h頭文件 --- 失敗了
4店归、手動修復(fù)參數(shù) --- 修改第一個參數(shù)JNIEnv*阎抒,修改第一個變量為env
5、理清計(jì)算過程消痛,讀懂偽代碼 --- 匯編沒有基礎(chǔ)且叁,基本看不懂
6、偽代碼轉(zhuǎn)換成c++代碼 --- 趕鴨子上架肄满,0基礎(chǔ)學(xué)習(xí)簡單的c++語法谴古,解決各種傻缺的問題(比如沒定義變量,格式警告稠歉,掰担;號結(jié)尾等等)
7、學(xué)習(xí)到了別人的解題思路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怒炸,一起剝皮案震驚了整個濱河市带饱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阅羹,老刑警劉巖勺疼,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捏鱼,居然都是意外死亡执庐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門导梆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轨淌,“玉大人迂烁,你說我怎么就攤上這事〉蒺模” “怎么了盟步?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長躏结。 經(jīng)常有香客問我却盘,道長,這世上最難降的妖魔是什么媳拴? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任黄橘,我火速辦了婚禮,結(jié)果婚禮上禀挫,老公的妹妹穿的比我還像新娘旬陡。我一直安慰自己,他們只是感情好语婴,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驶睦,像睡著了一般砰左。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上场航,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天缠导,我揣著相機(jī)與錄音,去河邊找鬼溉痢。 笑死僻造,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的孩饼。 我是一名探鬼主播髓削,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼镀娶!你這毒婦竟也來了立膛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤宪彩,失蹤者是張志新(化名)和其女友劉穎译隘,沒想到半個月后墙牌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡儿奶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳄抒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯捎。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡搅窿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隙券,到底是詐尸還是另有隱情男应,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布娱仔,位于F島的核電站沐飘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏牲迫。R本人自食惡果不足惜耐朴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盹憎。 院中可真熱鬧筛峭,春花似錦、人聲如沸陪每。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檩禾。三九已至挂签,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盼产,已是汗流浹背饵婆。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戏售,地道東北人侨核。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像灌灾,于是被迫代替她去往敵國和親搓译。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容