Activity插件化原理第二種方案:Hook IActivityManager

人生一切難題辆沦,知識(shí)給你答案

溫馨提示:閱讀本文需要20-30分鐘(一大波代碼)
關(guān)注公眾號(hào):顧林海


今天,我們來(lái)解決一個(gè)問(wèn)題:

Activity插件化原理第二種方案:Hook IActivityManager

人生一切難題贤笆,知識(shí)給你答案阻逮。


第一種方案Hook Instrumentation已經(jīng)順利完成盲赊,接下來(lái)我們看第二個(gè)方案坦胶,還是看這段代碼:

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            //Activity啟動(dòng)
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

通過(guò)mInstrumentation的execStartActivity方法啟動(dòng)Activity,在execStartActivity方法中會(huì)獲取AMS的代理滤奈,Android 7.0通過(guò)ActivityManagerNative的getDefault方法獲取一個(gè)ActivityManagerProxy摆昧,這個(gè)ActivityManagerProxy內(nèi)部封裝了IBinder類(lèi)型的ActivityManagerService的代理類(lèi),這樣在應(yīng)用程序進(jìn)程中就可以通過(guò)這個(gè)ActivityManagerProxy與SystemServer進(jìn)程的ActivityManagerService進(jìn)行通信蜒程,而在Android 8.0去除了ActivityManagerProxy這個(gè)代理類(lèi)绅你,由IActivityManager代替,這里的IActivityManager.aidl通過(guò)AIDL工具自動(dòng)生成IActivityManager.java昭躺。

Android 7.0-Activity啟動(dòng)

ActivityManager是一個(gè)和AMS相關(guān)聯(lián)的類(lèi)忌锯,它主要對(duì)運(yùn)行中的Activity進(jìn)行管理,ActivityManager中相關(guān)管理方法最終會(huì)通過(guò)ActivityManagerNative的getDefault方法來(lái)得到ActivityManagerProxy窍仰,再調(diào)用ActivityManagerProxy的相關(guān)管理方法汉规,ActivityManagerProxy就是AMS的代理類(lèi),通過(guò)這個(gè)代理類(lèi)就可以和AMS進(jìn)行通信驹吮。

Android7.0的Activity啟動(dòng)過(guò)程會(huì)調(diào)用Instrumentation的execStartActivity方法针史,代碼如下:

public ActivityResult execStartActivity(
        ...
        try {
            ...
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

在execStartActivity方法中會(huì)調(diào)用ActivityManagerNative的getDefault方法來(lái)獲取ActivityManagerProxy,ActivityManagerProxy又是AMS的代理類(lèi)碟狞,這樣的話就可以通過(guò)ActivityManagerProxy向AMS發(fā)送startActivity的請(qǐng)求啄枕。

ActivityManagerNative的getDefault方法的代碼如下:

   private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            ...
            IActivityManager am = asInterface(b);
            ...
            return am;
        }
    };

    static public IActivityManager getDefault() {
        return gDefault.get();
    }

在getDefault方法中調(diào)用了gDefault的get方法,gDefault是一個(gè)單例類(lèi)族沃。通過(guò)ServiceManager的getService方法獲取一個(gè)IBinder類(lèi)型的AMS的引用频祝,再將它通過(guò)asInterface方法轉(zhuǎn)換成ActivityManagerProxy類(lèi)型的對(duì)象。

asInterface方法:

static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        //檢查本地進(jìn)程是否有IActivityManager接口的實(shí)現(xiàn)
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //本地進(jìn)程沒(méi)有IActivityManager接口的實(shí)現(xiàn)脆淹,將IBinder類(lèi)型的AMS引用封裝成AMP
        return new ActivityManagerProxy(obj);
    }

在asInterface方法中分兩種情況常空,首先會(huì)檢查本地進(jìn)程是否有IActivityManager接口的實(shí)現(xiàn),如果有就直接返回盖溺;如果沒(méi)有漓糙,就將IBinder類(lèi)型的AMS引用封裝成ActivityManagerProxy。

public abstract class ActivityManagerNative extends Binder implements IActivityManager{
    ...
    class ActivityManagerProxy implements IActivityManager{
        public ActivityManagerProxy(IBinder remote){
            mRemote = remote;
        }
                ...
    }
    ...
}

ActivityManagerProxy是ActivityManagerNative的內(nèi)部類(lèi)烘嘱,在ActivityManagerProxy的構(gòu)造方法中將AMS的引用賦值給變量mRemote昆禽,這樣在ActivityManagerProxy中就可以使用AMS了蝗蛙。

繼續(xù)回到Instrumentation的execStartActivity方法,代碼如下:

public ActivityResult execStartActivity(
        ...
        try {
            ...
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

通過(guò)ActivityManagerNative的getDefault方法獲取AMS的代理類(lèi)ActivityManagerProxy醉鳖,再調(diào)用ActivityManagerProxy的startActivity方法捡硅。

ActivityManagerProxy的startActivity方法:

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        ...
        //向AMS發(fā)送START_ACTIVITY_TRANSACTION類(lèi)型的進(jìn)程間通信請(qǐng)求
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

在ActivityManagerProxy的startActivity方法中,通過(guò)mRemote盗棵,也就是AMS的引用壮韭,向服務(wù)端的AMS發(fā)送一個(gè)START_ACTIVITY_TRANSACTION類(lèi)型的進(jìn)程間通信請(qǐng)求,服務(wù)端AMS就會(huì)從Binder線程池中讀取客戶(hù)端發(fā)來(lái)的數(shù)據(jù)漾根,最終會(huì)調(diào)用ActivityManagerNative的onTransact方法泰涂。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
    switch (code) {
        case START_ACTIVITY_TRANSACTION:{
            ...
            int result = startActivity(app, callingPackage, intent, resolvedType,
            ...
            return true;
        }
        ...
    }

    return super.onTransact(code, data, reply, flags);
}

同時(shí)ActivityManagerService繼承自ActivityManagerNative鲫竞,因此onTransact方法的switch語(yǔ)句的START_ACTIVITY_TRANSACTION分支會(huì)調(diào)用AMS的startActivity辐怕。

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    @Override    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
           int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
      }
}

Android 8.0-Activity啟動(dòng)

Android8.0和7.0的Activity啟動(dòng)過(guò)程都會(huì)調(diào)用Instrumentation的execStartActivity方法,代碼如下:

    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
        ...
        try {
            ...
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

在execStartActivity方法中通過(guò)ActivityManager的getService獲取IActivityManager對(duì)象从绘,并通過(guò)IActivityManager對(duì)象的startActivity方法通知AMS啟動(dòng)Activity寄疏。

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

IActivityManagerSingleto是一個(gè)單例類(lèi),在它的create方法中獲取iBinder類(lèi)型的AMS引用僵井,接著通過(guò)AIDL陕截,將AMS應(yīng)用轉(zhuǎn)換成IActivityManager類(lèi)型的對(duì)象。相比于Android 7.0來(lái)說(shuō)批什,這里去掉了ActivityManagerProxy這個(gè)代理類(lèi)农曲,由IActivityManager代替,這里的IActivityManager.aidl通過(guò)AIDL工具自動(dòng)生成IActivityManager.java驻债。

通過(guò)Android 7.0和Android 8.0的Activity啟動(dòng)流程可以得出Activity插件化的另一種方案:Hook IActivityManager乳规,通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)。

首先創(chuàng)建占坑Activity:

public class StubActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stub);
    }
}

創(chuàng)建插件Activity:

public class TargetActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_target);
    }
}

并在AndroidManifest.xml中注冊(cè)占坑Activity:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.glh.haiproject01">

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="AllowBackup,GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".StubActivity" />
    </application>

</manifest>

在AndroidManifest.xml中沒(méi)有注冊(cè)插件Activity合呐,這時(shí)如果啟動(dòng)插件Activity會(huì)報(bào)錯(cuò)暮的。

接著開(kāi)始Hook IActivityManager,創(chuàng)建代理類(lèi)IActivityManagerProxy:

public class IActivityManagerProxy implements InvocationHandler {

    private Object mActivityManager;

    public IActivityManagerProxy(Object activityManager){
        this.mActivityManager=activityManager;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("startActivity".equals(method.getName())){
            //攔截startActivity
            Intent intent=null;
            int index=0;
            for(int i=0,length=args.length;i<length;i++){
                if(args[i] instanceof Intent){
                    index=i;
                    break;
                }
            }
            //獲取插件Activity的Intent
            intent= (Intent) args[index];
            //創(chuàng)建占坑Activity的Intent
            Intent subIntent=new Intent();
            subIntent.setClassName("com.glh.haiproject01","com.glh.haiproject01.StubActivity");
            //保存插件Activity的Intent
            subIntent.putExtra(HookHelper.REQUEST_TARGET_INTENT_NAME,intent);
            //替換為占坑Activity
            args[index]=subIntent;
        }
        return method.invoke(mActivityManager,args);
    }
}

IActivityManagerProxy代理類(lèi)的invoke非常簡(jiǎn)單淌实,就是將插件Activity的Intent替換為占坑Activity的Intent冻辩,并保存插件Activity的Intent,方便后續(xù)還原拆祈。

    private void hookIActivityManager(){
        Object defaultSingleton;
        if(Build.VERSION.SDK_INT==26){
            //Android 8.0
            defaultSingleton=getIActivityManagerSingleton();
        }else{
            defaultSingleton=getDefault();
        }
        try {
            Class<?> singletonClazz=Class.forName("android.util.Singleton");
            Field instanceField=singletonClazz.getDeclaredField("mInstance");
            instanceField.setAccessible(true);
            //獲取defaultSingleton中IActivityManager類(lèi)型的mInstance成員變量
            Object iActivityManager=instanceField.get(defaultSingleton);

            Class<?> iActivityManagerClazz=Class.forName("android.app.IActivityManager");
            Object proxy=Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class<?>[]{iActivityManagerClazz},new IActivityManagerProxy(iActivityManager));
            //替換為代理類(lèi)IActivityManagerProxy
            instanceField.set(defaultSingleton,proxy);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private Object getIActivityManagerSingleton(){
        try {
            Class<?> activityManagerClazz=Class.forName("android.app.ActivityManager");
            Field field=activityManagerClazz.getDeclaredField("IActivityManagerSingleton");
            field.setAccessible(true);
            return field.get(null);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private Object getDefault(){
        try {
            Class<?> activityManagerClazz=Class.forName("android.app.ActivityManagerNative");
            Field field=activityManagerClazz.getDeclaredField("gDefault");
            field.setAccessible(true);
            return field.get(null);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

以上代碼主要就是將Singleton的IActivityManager類(lèi)型的成員變量mInstance替換成通過(guò)動(dòng)態(tài)代理對(duì)象恨闪。當(dāng)我們向AMS請(qǐng)求啟動(dòng)Activity時(shí),會(huì)執(zhí)行代理類(lèi)IActivityManagerProxy的invoke方法進(jìn)行貍貓換太子放坏。

當(dāng)AMS通過(guò)驗(yàn)證后需要還原插件Activity的Intent咙咽,在Android 8.0和Android 7.0(其他版本源碼有可能不同)中,AMS通過(guò)Binder跨進(jìn)程調(diào)用scheduleLaunchActivity轻姿,scheduleLaunchActivity方法在應(yīng)用程序進(jìn)程的Binder線程池中犁珠,通過(guò)mH發(fā)送LAUNCH_ACTIVITY消息(100)切換到主線程中創(chuàng)建并啟動(dòng)Activity逻炊。

mH的類(lèi)型是ActivityThread中的內(nèi)部類(lèi)H,H繼承自Handler并實(shí)現(xiàn)了handleMessage方法犁享,在Handler源碼中余素,有這么一段代碼:

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

當(dāng)mCallback不為null時(shí)會(huì)調(diào)用handleMessage方法,mCallback類(lèi)型是Callback接口炊昆,因此我們可以Hook Callback桨吊,用自定的Callback替換Handler的mCallback。

代理Callback:

public class CallBackProxy implements Handler.Callback {

    private Handler mHandler;

    public CallBackProxy(Handler handler){
        this.mHandler=handler;
    }

    @Override
    public boolean handleMessage(Message msg) {
        if(msg.what==100){
            Object o=msg.obj;
            try {
                Field field=o.getClass().getDeclaredField("intent");
                field.setAccessible(true);
                //獲取占坑Activity的Intent
                Intent intent= (Intent) field.get(o);
                //獲取之前保存的插件Activity的Intent
                Intent targetIntent=intent.getParcelableExtra(HookHelper.REQUEST_TARGET_INTENT_NAME);
                //將占坑的Activity替換為插件Activity
                intent.setComponent(targetIntent.getComponent());
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        mHandler.handleMessage(msg);
        return true;
    }
}

將Handler的mCallback替換為代理類(lèi)CallBackProxy:

    private  void hookHandler(){
        try {
            Class<?> activityThreadClazz=Class.forName("android.app.ActivityThread");
            Field currentActivityThreadField=activityThreadClazz.getDeclaredField("sCurrentActivityThread");
            currentActivityThreadField.setAccessible(true);
            Object currentActivityThread=currentActivityThreadField.get(null);

            Field handlerField=activityThreadClazz.getDeclaredField("mH");
            handlerField.setAccessible(true);
            Handler mH= (Handler) handlerField.get(currentActivityThread);

            Field callbackField=Handler.class.getDeclaredField("mCallback");
            callbackField.setAccessible(true);
            //Handler的mCallback替換為CallBackProxy
            callbackField.set(mH,new CallBackProxy(mH));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

至此凤巨,Hook IActivityManager方案已經(jīng)完成视乐,在主界面中啟動(dòng)插件Activity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_startActivity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this,TargetActivity.class);
                startActivity(intent);
            }
        });
    }
}

運(yùn)行效果:

wq1.gif

838794-506ddad529df4cd4.webp.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市敢茁,隨后出現(xiàn)的幾起案子佑淀,更是在濱河造成了極大的恐慌,老刑警劉巖彰檬,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伸刃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡逢倍,警方通過(guò)查閱死者的電腦和手機(jī)捧颅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)较雕,“玉大人碉哑,你說(shuō)我怎么就攤上這事×两” “怎么了扣典?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)宛蚓。 經(jīng)常有香客問(wèn)我激捏,道長(zhǎng),這世上最難降的妖魔是什么凄吏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任远舅,我火速辦了婚禮,結(jié)果婚禮上痕钢,老公的妹妹穿的比我還像新娘图柏。我一直安慰自己,他們只是感情好任连,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蚤吹。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裁着。 梳的紋絲不亂的頭發(fā)上繁涂,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音二驰,去河邊找鬼扔罪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛桶雀,可吹牛的內(nèi)容都是我干的矿酵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼矗积,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼全肮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起棘捣,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辜腺,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后柱锹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體哪自,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丰包,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年禁熏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邑彪。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞧毙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寄症,到底是詐尸還是另有隱情宙彪,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布有巧,位于F島的核電站释漆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏篮迎。R本人自食惡果不足惜男图,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甜橱。 院中可真熱鬧逊笆,春花似錦、人聲如沸岂傲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至乃戈,卻和暖如春褂痰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背症虑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工脐恩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侦讨。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓驶冒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親韵卤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骗污,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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