1458 lines
68 KiB
HTML
1458 lines
68 KiB
HTML
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<html class="theme-next gemini use-motion" lang="zh-Hans">
|
||
<head><meta name="generator" content="Hexo 3.8.0">
|
||
<meta charset="UTF-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||
<meta name="theme-color" content="#222">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta http-equiv="Cache-Control" content="no-transform">
|
||
<meta http-equiv="Cache-Control" content="no-siteapp">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">
|
||
|
||
<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">
|
||
|
||
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="keywords" content="小米,路由器,调试,">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="description" content="0x00 背景与简介在分析嵌入式设备的固件时,只采用静态分析方式通常是不够的,你需要实际执行你的分析目标来观察它的行为。在嵌入式Linux设备的世界里,很容易把一个调试器放在目标硬件上进行调试。如果你能在自己的系统上运行二进制文件,而不是拖着硬件做分析, 将会方便很多,这就需要用QEMU进行仿真。虽然QEMU在模拟核心芯片组包括CPU上都做的很不错,但是QEMU往往不能提供你想运行的二进制程序需要">
|
||
<meta name="keywords" content="小米,路由器,调试">
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:title" content="远程调试小米路由器固件">
|
||
<meta property="og:url" content="https://cool-y.github.io/2019/07/25/Debug-a-router-firmware/index.html">
|
||
<meta property="og:site_name" content="混元霹雳手">
|
||
<meta property="og:description" content="0x00 背景与简介在分析嵌入式设备的固件时,只采用静态分析方式通常是不够的,你需要实际执行你的分析目标来观察它的行为。在嵌入式Linux设备的世界里,很容易把一个调试器放在目标硬件上进行调试。如果你能在自己的系统上运行二进制文件,而不是拖着硬件做分析, 将会方便很多,这就需要用QEMU进行仿真。虽然QEMU在模拟核心芯片组包括CPU上都做的很不错,但是QEMU往往不能提供你想运行的二进制程序需要">
|
||
<meta property="og:locale" content="zh-Hans">
|
||
<meta property="og:updated_time" content="2019-07-25T14:36:28.915Z">
|
||
<meta name="twitter:card" content="summary">
|
||
<meta name="twitter:title" content="远程调试小米路由器固件">
|
||
<meta name="twitter:description" content="0x00 背景与简介在分析嵌入式设备的固件时,只采用静态分析方式通常是不够的,你需要实际执行你的分析目标来观察它的行为。在嵌入式Linux设备的世界里,很容易把一个调试器放在目标硬件上进行调试。如果你能在自己的系统上运行二进制文件,而不是拖着硬件做分析, 将会方便很多,这就需要用QEMU进行仿真。虽然QEMU在模拟核心芯片组包括CPU上都做的很不错,但是QEMU往往不能提供你想运行的二进制程序需要">
|
||
|
||
|
||
|
||
<script type="text/javascript" id="hexo.configurations">
|
||
var NexT = window.NexT || {};
|
||
var CONFIG = {
|
||
root: '/',
|
||
scheme: 'Gemini',
|
||
version: '5.1.4',
|
||
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
|
||
fancybox: true,
|
||
tabs: true,
|
||
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
|
||
duoshuo: {
|
||
userId: '0',
|
||
author: '博主'
|
||
},
|
||
algolia: {
|
||
applicationID: '',
|
||
apiKey: '',
|
||
indexName: '',
|
||
hits: {"per_page":10},
|
||
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
|
||
|
||
<link rel="canonical" href="https://cool-y.github.io/2019/07/25/Debug-a-router-firmware/">
|
||
|
||
|
||
|
||
|
||
|
||
<title>远程调试小米路由器固件 | 混元霹雳手</title>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</head>
|
||
|
||
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container sidebar-position-left page-post-detail">
|
||
<div class="headband"></div>
|
||
|
||
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
|
||
<div class="header-inner"><div class="site-brand-wrapper">
|
||
<div class="site-meta ">
|
||
|
||
|
||
<div class="custom-logo-site-title">
|
||
<a href="/" class="brand" rel="start">
|
||
<span class="logo-line-before"><i></i></span>
|
||
<span class="site-title">混元霹雳手</span>
|
||
<span class="logo-line-after"><i></i></span>
|
||
</a>
|
||
</div>
|
||
|
||
<p class="site-subtitle"></p>
|
||
|
||
</div>
|
||
|
||
<div class="site-nav-toggle">
|
||
<button>
|
||
<span class="btn-bar"></span>
|
||
<span class="btn-bar"></span>
|
||
<span class="btn-bar"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="site-nav">
|
||
|
||
|
||
|
||
<ul id="menu" class="menu">
|
||
|
||
|
||
<li class="menu-item menu-item-home">
|
||
<a href="/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-home"></i> <br>
|
||
|
||
首页
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-about">
|
||
<a href="/about/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-user"></i> <br>
|
||
|
||
关于
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-tags">
|
||
<a href="/tags/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
|
||
|
||
标签
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-categories">
|
||
<a href="/categories/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-th"></i> <br>
|
||
|
||
分类
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-archives">
|
||
<a href="/archives/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
|
||
|
||
归档
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-bookmarks">
|
||
<a href="/bookmarks/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-map"></i> <br>
|
||
|
||
书签
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-hack之外">
|
||
<a href="/hack之外/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br>
|
||
|
||
HACK之外
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
<li class="menu-item menu-item-search">
|
||
|
||
<a href="javascript:;" class="popup-trigger">
|
||
|
||
|
||
<i class="menu-item-icon fa fa-search fa-fw"></i> <br>
|
||
|
||
搜索
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<div class="site-search">
|
||
|
||
<div class="popup search-popup local-search-popup">
|
||
<div class="local-search-header clearfix">
|
||
<span class="search-icon">
|
||
<i class="fa fa-search"></i>
|
||
</span>
|
||
<span class="popup-btn-close">
|
||
<i class="fa fa-times-circle"></i>
|
||
</span>
|
||
<div class="local-search-input-wrapper">
|
||
<input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input">
|
||
</div>
|
||
</div>
|
||
<div id="local-search-result"></div>
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
</div>
|
||
</header>
|
||
|
||
<main id="main" class="main">
|
||
<div class="main-inner">
|
||
<div class="content-wrap">
|
||
<div id="content" class="content">
|
||
|
||
|
||
<div id="posts" class="posts-expand">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
|
||
|
||
|
||
|
||
<div class="post-block">
|
||
<link itemprop="mainEntityOfPage" href="https://cool-y.github.io/2019/07/25/Debug-a-router-firmware/">
|
||
|
||
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||
<meta itemprop="name" content="Cool-Y">
|
||
<meta itemprop="description" content>
|
||
<meta itemprop="image" content="/images/avatar.png">
|
||
</span>
|
||
|
||
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
|
||
<meta itemprop="name" content="混元霹雳手">
|
||
</span>
|
||
|
||
|
||
<header class="post-header">
|
||
|
||
|
||
|
||
<h1 class="post-title" itemprop="name headline">远程调试小米路由器固件</h1>
|
||
|
||
|
||
<div class="post-meta">
|
||
<span class="post-time">
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-calendar-o"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">发表于</span>
|
||
|
||
<time title="创建于" itemprop="dateCreated datePublished" datetime="2019-07-25T22:17:08+08:00">
|
||
2019-07-25
|
||
</time>
|
||
|
||
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
<span class="post-category">
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-folder-o"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">分类于</span>
|
||
|
||
|
||
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
|
||
<a href="/categories/IOT/" itemprop="url" rel="index">
|
||
<span itemprop="name">IOT</span>
|
||
</a>
|
||
</span>
|
||
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<span id="/2019/07/25/Debug-a-router-firmware/" class="leancloud_visitors" data-flag-title="远程调试小米路由器固件">
|
||
<span class="post-meta-divider">|</span>
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-eye"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">阅读次数:</span>
|
||
|
||
<span class="leancloud-visitors-count"></span>
|
||
</span>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-wordcount">
|
||
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-file-word-o"></i>
|
||
</span>
|
||
|
||
<span title="字数统计">
|
||
3k 字
|
||
</span>
|
||
|
||
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
|
||
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-clock-o"></i>
|
||
</span>
|
||
|
||
<span title="阅读时长">
|
||
13 分钟
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</header>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-body" itemprop="articleBody">
|
||
|
||
|
||
|
||
|
||
|
||
<h1 id="0x00-背景与简介"><a href="#0x00-背景与简介" class="headerlink" title="0x00 背景与简介"></a>0x00 背景与简介</h1><p>在分析嵌入式设备的固件时,只采用静态分析方式通常是不够的,你需要实际执行你的分析目标来观察它的行为。在嵌入式Linux设备的世界里,很容易把一个调试器放在目标硬件上进行调试。如果你能在自己的系统上运行二进制文件,而不是拖着硬件做分析, 将会方便很多,这就需要用QEMU进行仿真。<br>虽然QEMU在模拟核心芯片组包括CPU上都做的很不错,但是QEMU往往不能提供你想运行的二进制程序需要的硬件。最常见问题是在运行系统服务,如Web服务器或UPnP守护进程时,缺乏NVRAM。解决方法是使用nvram-faker库拦截由libnvram.so提供的nvram_get()调用。即使解决了NVRAM问题,该程序还可能会假设某些硬件是存在的,如果硬件不存在,该程序可能无法运行,或者即便它运行了,行为可能也与在其目标硬件上运行时有所不同。针对这种情况下,我认为有三种解决方法:</p>
|
||
<ol>
|
||
<li>修补二进制文件。这取决于期望什么硬件,以及它不存在时的行为是什么。</li>
|
||
<li>把复杂的依赖于硬件的系统服务拆分成小的二级制文件。如跳过运行Web服务器,仅仅从shell脚本运行cgi二进制文件。因为大多数cgi二进制文件将来自Web服务器的输入作为标准输入和环境变量的组合,并通过标准输出将响应发送到Web服务器。</li>
|
||
<li>拿到设备的shell,直接在真机上进行调试,这是最接近真实状况的方法。</li>
|
||
</ol>
|
||
<hr>
|
||
<h1 id="REF"><a href="#REF" class="headerlink" title="REF"></a>REF</h1><p><strong>综合:</strong><br><a href="https://shadow-file.blogspot.com/2015/01/dynamically-analyzing-wifi-routers-upnp.html" target="_blank" rel="noopener">国外大神的博客</a><br><a href="https://wooyun.js.org/drops/%E9%80%9A%E8%BF%87QEMU%20%E5%92%8C%20IDA%20Pro%E8%BF%9C%E7%A8%8B%E8%B0%83%E8%AF%95%E8%AE%BE%E5%A4%87%E5%9B%BA%E4%BB%B6.html" target="_blank" rel="noopener">通过QEMU和IDAPro远程调试设备固件</a><br><a href="https://ray-cp.github.io/archivers/MIPS_Debug_Environment_and_Stack_Overflow" target="_blank" rel="noopener">MIPS漏洞调试环境安装及栈溢出</a><br><a href="https://wiki.x10sec.org/pwn/arm/environment/" target="_blank" rel="noopener">环境搭建onCTFWIKI</a><br><a href="https://www.anquanke.com/post/id/171918" target="_blank" rel="noopener">路由器漏洞训练平台</a><br><a href="https://www.anquanke.com/post/id/180714" target="_blank" rel="noopener">路由器0day漏洞挖掘实战</a><br><a href="https://5alt.me/wiki/%E9%80%86%E5%90%91" target="_blank" rel="noopener">逆向常用工具</a></p>
|
||
<p><strong>环境搭建:</strong><br><a href="https://xz.aliyun.com/t/3826" target="_blank" rel="noopener">路由器漏洞挖掘测试环境的搭建之问题总结</a></p>
|
||
<p><strong>Linux相关知识</strong><br><a href="http://xstarcd.github.io/wiki/Cloud/qcow2_raw_vmdk.html" target="_blank" rel="noopener">qcow2、raw、vmdk等镜像格式</a><br><a href="http://joe.is-programmer.com/posts/17753.html" target="_blank" rel="noopener">Linux 引导过程内幕</a><br><a href="https://zhuanlan.zhihu.com/p/32051645" target="_blank" rel="noopener">Linux启动过程</a></p>
|
||
<p><strong>调试案例</strong><br><a href="https://xz.aliyun.com/t/5681" target="_blank" rel="noopener">CVE-2019-10999复现</a><br><a href="https://ray-cp.github.io/archivers/router_vuln_book_note" target="_blank" rel="noopener">《家用路由器0day漏洞挖掘》部分案例</a><br><a href="https://paper.seebug.org/448/" target="_blank" rel="noopener">TP-LINK WR941N路由器研究</a></p>
|
||
<hr>
|
||
<h1 id="0x01-基础条件"><a href="#0x01-基础条件" class="headerlink" title="0x01 基础条件"></a>0x01 基础条件</h1><ul>
|
||
<li><p>一系列的工具,包括:<br><strong>binwalk</strong> 帮助你解包固件<br><strong>buildroot</strong> mips交叉编译环境帮助你在x86平台下编译mips架构的目标程序 <a href="https://xz.aliyun.com/t/2505#toc-6" target="_blank" rel="noopener">https://xz.aliyun.com/t/2505#toc-6</a><br><strong>qemu</strong> 帮助你模拟mips环境<br><strong>MIPS gdbinit</strong> 文件使得使用gdb调试mips程序时更方便 <a href="https://github.com/zcutlip/gdbinit-mips" target="_blank" rel="noopener">https://github.com/zcutlip/gdbinit-mips</a><br><strong>miranda工具</strong> 用于UPnP分析 <a href="https://code.google.com/p/miranda-upnp/" target="_blank" rel="noopener">https://code.google.com/p/miranda-upnp/</a><br><strong>MIPS静态汇编审计</strong> 辅助脚本 <a href="https://github.com/giantbranch/mipsAudit" target="_blank" rel="noopener">https://github.com/giantbranch/mipsAudit</a><br><strong>静态编译的gdbserver</strong> <a href="https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver" target="_blank" rel="noopener">https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver</a></p>
|
||
</li>
|
||
<li><p>一个<strong>mips Linux</strong>环境:<br>在qemu系统模式下,需要模拟整个计算机系统</p>
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<h1 id="0x02-qemu-用户模式"><a href="#0x02-qemu-用户模式" class="headerlink" title="0x02 qemu-用户模式"></a>0x02 qemu-用户模式</h1><p>在user mode下使用qemu执行程序有两种情况,一是目标程序为<strong>静态链接</strong>,那么可以直接使用qemu。另一种是目标程序依赖于<strong>动态链接</strong>库,这时候就需要我们来<strong>指明库的位置</strong>,否则目标程序回到系统<code>/lib</code>文件下寻找共享库文件。<br>在 <em>《揭秘家用路由器0day》</em> 这本书里面,他给出的方法是:<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span> cp $(which qemu-mipsel) ./</span><br><span class="line"><span class="meta">$</span> sudo chroot . ./qemu-mipsel ./usr/sbin/miniupnpd</span><br></pre></td></tr></table></figure></p>
|
||
<p>他把qemu-mipsel复制到固件文件目录下,然后<code>chroot</code>命令改变qemu执行的根目录到当前目录,按理说此时应该可以找到依赖库,但是结果却是<code>chroot: failed to run command ‘./qemu-mipsel’: No such file or directory</code></p>
|
||
<p>在网上找到了<a href="https://xz.aliyun.com/t/3826" target="_blank" rel="noopener">解决方法</a>:需要安装使用 <strong>qemu-mips-static</strong> 才可以<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span> apt-get install qemu binfmt-support qemu-user-static</span><br><span class="line"><span class="meta">$</span> cp $(which qemu-mipsel-static ) ./</span><br><span class="line"><span class="meta">$</span> sudo chroot . ./qemu-mipsel-static ./usr/sbin/miniupnpd</span><br></pre></td></tr></table></figure></p>
|
||
<p>这里还可利用<code>-E</code>用来设置环境变量,<code>LD_PRELOAD "./lib"</code>用来劫持系统调用,另外还有<code>-g</code>开启调试模式</p>
|
||
<p>除此之外,也在<a href="https://wiki.x10sec.org/pwn/arm/environment/" target="_blank" rel="noopener">CTF-WIKI</a>上找到了另一种方法:使用 <strong>qemu-mips 的 -L 参数</strong>指定路由器的根目录<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span> qemu-mipsel -L . ./usr/sbin/miniupnpd</span><br></pre></td></tr></table></figure></p>
|
||
<h2 id="模拟miniupnp"><a href="#模拟miniupnp" class="headerlink" title="模拟miniupnp"></a>模拟miniupnp</h2><p>由于没有指定参数,所以这里miniupnpd只把usage和notes打印给我们了:<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">Usage:</span><br><span class="line"> ./usr/sbin/miniupnpd [-f config_file] [-i ext_ifname] [-o ext_ip]</span><br><span class="line"> [-a listening_ip] [-p port] [-d] [-U] [-S] [-N]</span><br><span class="line"> [-u uuid] [-s serial] [-m model_number]</span><br><span class="line"> [-t notify_interval] [-P pid_filename]</span><br><span class="line"> [-B down up] [-w url] [-r clean_ruleset_interval]</span><br><span class="line"> [-A "permission rule"] [-b BOOTID]</span><br><span class="line"></span><br><span class="line">Notes:</span><br><span class="line"> There can be one or several listening_ips.</span><br><span class="line"> Notify interval is in seconds. Default is 30 seconds.</span><br><span class="line"> Default pid file is '/var/run/miniupnpd.pid'.</span><br><span class="line"> Default config file is '/etc/miniupnpd.conf'.</span><br><span class="line"> With -d miniupnpd will run as a standard program.</span><br><span class="line"> -S sets "secure" mode : clients can only add mappings to their own ip</span><br><span class="line"> -U causes miniupnpd to report system uptime instead of daemon uptime.</span><br><span class="line"> -N enables NAT-PMP functionality.</span><br><span class="line"> -B sets bitrates reported by daemon in bits per second.</span><br><span class="line"> -w sets the presentation url. Default is http address on port 80</span><br><span class="line"> -A use following syntax for permission rules :</span><br><span class="line"> (allow|deny) (external port range) ip/mask (internal port range)</span><br><span class="line"> examples :</span><br><span class="line"> "allow 1024-65535 192.168.1.0/24 1024-65535"</span><br><span class="line"> "deny 0-65535 0.0.0.0/0 0-65535"</span><br><span class="line"> -b sets the value of BOOTID.UPNP.ORG SSDP header</span><br><span class="line"> -h prints this help and quits.</span><br></pre></td></tr></table></figure></p>
|
||
<p>根据miniupnpd的启动文件<code>/etc/init.d/miniupnpd</code>,小米使用了启动脚本来配置<code>service_start /usr/sbin/miniupnpd -f conffile -d</code><br>其配置文件connfile如下所示:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ext_ifname=eth0.2</span><br><span class="line">listening_ip=br-lan</span><br><span class="line">port=5351</span><br><span class="line">enable_natpmp=yes</span><br><span class="line">enable_upnp=yes</span><br><span class="line">secure_mode=no</span><br><span class="line">system_uptime=yes</span><br><span class="line">lease_file=/tmp/upnp.leases</span><br><span class="line">bitrate_down=8388608</span><br><span class="line">bitrate_up=4194304</span><br><span class="line">uuid=e1f3a0ec-d9d4-4317-a14b-130cdd18d092</span><br><span class="line">allow 1024-65535 0.0.0.0/0 1024-65535</span><br><span class="line">deny 0-65535 0.0.0.0/0 0-65535</span><br></pre></td></tr></table></figure></p>
|
||
<ul>
|
||
<li style="list-style: none"><input type="checkbox"> 可见因路由器的特殊性,具有两张网卡(eth0.2&br-lan),暂时我还没想出应该怎么解决,是否采用qemu虚拟机配置网络可以解决呢?反正我采用下面这种粗暴的方式是不可以的(直接指定配置文件)<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span> sudo qemu-mipsel -L . ./usr/sbin/miniupnpd -f ../../MiniUPnP/miniupnpd.conf -d</span><br><span class="line">miniupnpd[7687]: system uptime is 5652 seconds</span><br><span class="line">miniupnpd[7687]: iptc_init() failed : iptables who? (do you need to insmod?)</span><br><span class="line">miniupnpd[7687]: Failed to init redirection engine. EXITING</span><br></pre></td></tr></table></figure>
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<h1 id="0x03-qemu-系统模式"><a href="#0x03-qemu-系统模式" class="headerlink" title="0x03 qemu-系统模式"></a>0x03 qemu-系统模式</h1><p>系统模式命令格式:<code>$qemu system-mips [option][disk_image]</code></p>
|
||
<h2 id="MIPS系统网络配置"><a href="#MIPS系统网络配置" class="headerlink" title="MIPS系统网络配置"></a>MIPS系统网络配置</h2><p>下载mips系统内核和虚拟机镜像 <a href="https://people.debian.org/~aurel32/qemu/" target="_blank" rel="noopener">https://people.debian.org/~aurel32/qemu/</a><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">To use this image, you need to install QEMU 1.1.0 (or later). Start QEMU</span><br><span class="line">with the following arguments for a 32-bit machine:</span><br><span class="line"> - qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"</span><br><span class="line"> - qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"</span><br></pre></td></tr></table></figure></p>
|
||
<p><strong>1. 安装依赖文件</strong><code>apt-get install uml-utilities bridge-utils</code></p>
|
||
<p><strong>2. 修改主机网络配置</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">auto lo</span><br><span class="line">iface lo inet loopback</span><br><span class="line"></span><br><span class="line">auto ens33</span><br><span class="line">iface eth0 inet dhcp</span><br><span class="line"></span><br><span class="line">#auto br0</span><br><span class="line">iface br0 inet dhcp</span><br><span class="line"> bridge_ports ens33</span><br><span class="line"> bridge_maxwait 0</span><br></pre></td></tr></table></figure></p>
|
||
<p><strong>3. 修改qemu网络接口启动脚本</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ sudo vim /etc/qemu-ifup </span><br><span class="line">$ sudo chmod a+x /etc/qemu-ifup</span><br><span class="line">#!/bin/sh</span><br><span class="line">echo "Executing /etc/qemu-ifup"</span><br><span class="line">echo "Bringing $1 for bridged mode..."</span><br><span class="line">sudo /sbin/ifconfig $1 0.0.0.0 promisc up</span><br><span class="line">echo "Adding $1 to br0..."</span><br><span class="line">sudo /sbin/brctl addif br0 $1</span><br><span class="line">sleep 3</span><br></pre></td></tr></table></figure></p>
|
||
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo /etc/init.d/networking restart</span><br></pre></td></tr></table></figure>
|
||
<p><strong>4. qemu启动配置</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ifdown ens33</span><br><span class="line">$ sudo ifup br0</span><br></pre></td></tr></table></figure></p>
|
||
<p><strong>5. 启动mips虚拟机</strong><br><code>sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic,macaddr=00:16:3e:00:00:01 -net tap -nographic</code></p>
|
||
<p>我自闭了,ubuntu18根本没法联网,于是我用了ubuntu14.0</p>
|
||
<hr>
|
||
<h1 id="0x04-在mips虚拟机中调试"><a href="#0x04-在mips虚拟机中调试" class="headerlink" title="0x04 在mips虚拟机中调试"></a>0x04 在mips虚拟机中调试</h1><p>现在通过上面的配置我得到了这样一台虚拟机,并通过ssh连接上去。<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# ifconfig</span><br><span class="line">eth1 Link encap:Ethernet HWaddr 00:16:3e:00:00:01</span><br><span class="line"> inet addr:192.168.31.246 Bcast:192.168.31.255 Mask:255.255.255.0</span><br><span class="line"> inet6 addr: fe80::216:3eff:fe00:1/64 Scope:Link</span><br><span class="line"> UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1</span><br><span class="line"> RX packets:89377 errors:75 dropped:360 overruns:0 frame:0</span><br><span class="line"> TX packets:9114 errors:0 dropped:0 overruns:0 carrier:0</span><br><span class="line"> collisions:0 txqueuelen:1000</span><br><span class="line"> RX bytes:103978997 (99.1 MiB) TX bytes:924287 (902.6 KiB)</span><br><span class="line"> Interrupt:10 Base address:0x1020</span><br><span class="line"></span><br><span class="line">lo Link encap:Local Loopback</span><br><span class="line"> inet addr:127.0.0.1 Mask:255.0.0.0</span><br><span class="line"> inet6 addr: ::1/128 Scope:Host</span><br><span class="line"> UP LOOPBACK RUNNING MTU:16436 Metric:1</span><br><span class="line"> RX packets:8 errors:0 dropped:0 overruns:0 frame:0</span><br><span class="line"> TX packets:8 errors:0 dropped:0 overruns:0 carrier:0</span><br><span class="line"> collisions:0 txqueuelen:0</span><br><span class="line"> RX bytes:560 (560.0 B) TX bytes:560 (560.0 B)</span><br></pre></td></tr></table></figure></p>
|
||
<p>已经把我的小米固件全部上传到这个虚拟机中<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# ls</span><br><span class="line">bin data dev etc extdisks lib libnvram-faker.so mnt opt overlay proc qemu-mipsel-static readonly rom root sbin sys tmp userdisk usr var www</span><br></pre></td></tr></table></figure></p>
|
||
<p>和用户模式一样,还是使用chroot,因为目标二进制是和固件的库链接的,很可能不能跟Debian的共享库一起工作。<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# chroot . ./usr/sbin/miniupnpd</span><br><span class="line">Usage:</span><br><span class="line"> ./usr/sbin/miniupnpd [-f config_file] [-i ext_ifname] [-o ext_ip]</span><br><span class="line"> [-a listening_ip] [-p port] [-d] [-U] [-S] [-N]</span><br><span class="line"> [-u uuid] [-s serial] [-m model_number]</span><br><span class="line"> [-t notify_interval] [-P pid_filename]</span><br><span class="line"> [-B down up] [-w url] [-r clean_ruleset_interval]</span><br><span class="line"> [-A "permission rule"] [-b BOOTID]</span><br><span class="line"></span><br><span class="line">Notes:</span><br><span class="line"> There can be one or several listening_ips.</span><br><span class="line"> Notify interval is in seconds. Default is 30 seconds.</span><br><span class="line"> Default pid file is '/var/run/miniupnpd.pid'.</span><br><span class="line"> Default config file is '/etc/miniupnpd.conf'.</span><br><span class="line"> With -d miniupnpd will run as a standard program.</span><br><span class="line"> -S sets "secure" mode : clients can only add mappings to their own ip</span><br><span class="line"> -U causes miniupnpd to report system uptime instead of daemon uptime.</span><br><span class="line"> -N enables NAT-PMP functionality.</span><br><span class="line"> -B sets bitrates reported by daemon in bits per second.</span><br><span class="line"> -w sets the presentation url. Default is http address on port 80</span><br><span class="line"> -A use following syntax for permission rules :</span><br><span class="line"> (allow|deny) (external port range) ip/mask (internal port range)</span><br><span class="line"> examples :</span><br><span class="line"> "allow 1024-65535 192.168.1.0/24 1024-65535"</span><br><span class="line"> "deny 0-65535 0.0.0.0/0 0-65535"</span><br><span class="line"> -b sets the value of BOOTID.UPNP.ORG SSDP header</span><br><span class="line"> -h prints this help and quits.</span><br></pre></td></tr></table></figure></p>
|
||
<p>直接运行起来,还是只打印出usage,这里我注意到之前忽视的地方<code>Default config file is '/etc/miniupnpd.conf'.</code>,所以我不再使用<code>-f</code>参数来指定,而是把配置文件放在默认目录下,在小米路由器里,<code>ext_ifname</code>是外部ip,<code>listening_ip</code>是内部ip。但是我这里还没有开启两个,所以都赋值为一张网卡。<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ext_ifname=eth1</span><br><span class="line">listening_ip=eth1</span><br><span class="line">port=5351</span><br><span class="line">enable_natpmp=yes</span><br><span class="line">enable_upnp=yes</span><br><span class="line">secure_mode=no</span><br><span class="line">system_uptime=yes</span><br><span class="line">lease_file=/tmp/upnp.leases</span><br><span class="line">bitrate_down=8388608</span><br><span class="line">bitrate_up=4194304</span><br><span class="line">uuid=e1f3a0ec-d9d4-4317-a14b-130cdd18d092</span><br><span class="line">allow 1024-65535 0.0.0.0/0 1024-65535</span><br><span class="line">deny 0-65535 0.0.0.0/0 0-65535</span><br></pre></td></tr></table></figure></p>
|
||
<p>在这个配置下,运行miniupnp还是被告知<code>daemon(): No such file or directory</code><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# chroot . ./usr/sbin/miniupnpd</span><br><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# daemon(): No such file or directory</span><br></pre></td></tr></table></figure></p>
|
||
<p>我起初猜测是因为缺乏<code>NVRAM</code></p>
|
||
<blockquote>
|
||
<p>在运行系统服务,如Web服务器或UPnP守护进程时,缺乏NVRAM。非易失性RAM通常是包含配置参数的设备快速存储器的一个分区。当一个守护进程启动时,它通常会尝试查询NVRAM,获取其运行时配置信息。有时一个守护进程会查询NVRAM的几十甚至上百个参数。</p>
|
||
</blockquote>
|
||
<p>于是我运行二进制程序时,使用LD_PRELOAD对nvram-faker库进行预加载。它会拦截通常由libnvram.so提供的<code>nvram_get()</code>调用。nvram-faker会查询你提供的一个INI风格的配置文件,而不是试图查询NVRAM。<br>这里有一个链接:<a href="https://github.com/zcutlip/nvram-faker" target="_blank" rel="noopener">https://github.com/zcutlip/nvram-faker</a><br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# chroot . /bin/sh -c "LD_PRELOAD=/libnvram-faker.so /usr/sbin/miniupnpd"</span><br><span class="line">root@debian-mipsel:/home/user/mi_wifi_r3_112# daemon(): No such file or directory</span><br></pre></td></tr></table></figure></p>
|
||
<p>问题依然存在,daemon是在miniupnpd中常出现的词,猜测,会不会某些函数没有实现?这部分会比较麻烦,需要反汇编。<br>但是,我们不是可以拿到路由器的shell吗!干嘛还要用qemu模拟再调试,直接上真机!</p>
|
||
<hr>
|
||
<h1 id="0x05-设备上调试程序"><a href="#0x05-设备上调试程序" class="headerlink" title="0x05 设备上调试程序"></a>0x05 设备上调试程序</h1><blockquote>
|
||
<p>1、有shell权限<br>2、有静态编译的gdbserver或者gdb</p>
|
||
</blockquote>
|
||
<p>只要满足上面两个条件,我们就可以通过在路由器上运行<code>gdbserver_mipsle --attach 0.0.0.0:port PID</code> 以及 在你的电脑上使用 <strong>gdb-multiarch</strong> 进行调试(先指定架构,然后使用remote功能)轻松地调试设备上地mips程序。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pwndbg> set architecture mips (但大多数情况下这一步可以省略, 似乎 pwndbg 能自动识别架构)</span><br><span class="line">pwndbg> target remote localhost:1234</span><br></pre></td></tr></table></figure></p>
|
||
<p>能根据固件中的bin得知这是一个小端mips指令集的设备,gdbserver也不用自己编译,直接下载编译好的: <a href="https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver" target="_blank" rel="noopener">https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver</a><br>把gdbserver.mipsbe通过tftp上传到路由器的/tmp目录下,然后找到目标程序PID:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">root@XiaoQiang:/# ps |grep miniupnp</span><br><span class="line">12517 root 1772 S grep miniupnp</span><br><span class="line">28284 root 1496 S /usr/sbin/miniupnpd -f /var/etc/miniupnpd.conf</span><br></pre></td></tr></table></figure></p>
|
||
<p><strong>gdbserver attach</strong>这个进程,就可以通过<strong>gdb</strong>或者<strong>IDA</strong>远程调试这个程序</p>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div>
|
||
<div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
|
||
<div>您的支持将鼓励我继续创作!</div>
|
||
<button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
|
||
<span>打赏</span>
|
||
</button>
|
||
<div id="QR" style="display: none;">
|
||
|
||
|
||
<div id="wechat" style="display: inline-block">
|
||
<img id="wechat_qr" src="/images/Wechatpay.png" alt="Cool-Y 微信支付">
|
||
<p>微信支付</p>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="alipay" style="display: inline-block">
|
||
<img id="alipay_qr" src="/images/Alipay.png" alt="Cool-Y 支付宝">
|
||
<p>支付宝</p>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<footer class="post-footer">
|
||
|
||
<div class="post-tags">
|
||
|
||
<a href="/tags/小米/" rel="tag"># 小米</a>
|
||
|
||
<a href="/tags/路由器/" rel="tag"># 路由器</a>
|
||
|
||
<a href="/tags/调试/" rel="tag"># 调试</a>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-nav">
|
||
<div class="post-nav-next post-nav-item">
|
||
|
||
<a href="/2019/07/24/获取固件/" rel="next" title="获取固件的几种方法">
|
||
<i class="fa fa-chevron-left"></i> 获取固件的几种方法
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<span class="post-nav-divider"></span>
|
||
|
||
<div class="post-nav-prev post-nav-item">
|
||
|
||
<a href="/2019/10/25/PWNtw-start/" rel="prev" title="【Pwnable.tw】start">
|
||
【Pwnable.tw】start <i class="fa fa-chevron-right"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</footer>
|
||
</div>
|
||
|
||
|
||
|
||
</article>
|
||
|
||
|
||
|
||
<div class="post-spread">
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="comments" id="comments">
|
||
|
||
<div id="gitment-container"></div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="sidebar-toggle">
|
||
<div class="sidebar-toggle-line-wrap">
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<aside id="sidebar" class="sidebar">
|
||
|
||
<div class="sidebar-inner">
|
||
|
||
|
||
|
||
|
||
<ul class="sidebar-nav motion-element">
|
||
<li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
|
||
文章目录
|
||
</li>
|
||
<li class="sidebar-nav-overview" data-target="site-overview-wrap">
|
||
站点概览
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
<section class="site-overview-wrap sidebar-panel">
|
||
<div class="site-overview">
|
||
<div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||
|
||
<img class="site-author-image" itemprop="image" src="/images/avatar.png" alt="Cool-Y">
|
||
|
||
<p class="site-author-name" itemprop="name">Cool-Y</p>
|
||
<p class="site-description motion-element" itemprop="description">没人比我更懂中医#MAGA</p>
|
||
</div>
|
||
|
||
<nav class="site-state motion-element">
|
||
|
||
|
||
<div class="site-state-item site-state-posts">
|
||
|
||
<a href="/archives/">
|
||
|
||
<span class="site-state-item-count">23</span>
|
||
<span class="site-state-item-name">日志</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="site-state-item site-state-categories">
|
||
<a href="/categories/index.html">
|
||
<span class="site-state-item-count">7</span>
|
||
<span class="site-state-item-name">分类</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="site-state-item site-state-tags">
|
||
<a href="/tags/index.html">
|
||
<span class="site-state-item-count">43</span>
|
||
<span class="site-state-item-name">标签</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
|
||
<div class="links-of-author motion-element">
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="https://github.com/Cool-Y" target="_blank" title="GitHub">
|
||
|
||
<i class="fa fa-fw fa-github"></i>GitHub</a>
|
||
</span>
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="mailto:cool.yim@whu.edu.cn" target="_blank" title="E-Mail">
|
||
|
||
<i class="fa fa-fw fa-envelope"></i>E-Mail</a>
|
||
</span>
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="https://www.instagram.com/yan__han/" target="_blank" title="Instagram">
|
||
|
||
<i class="fa fa-fw fa-instagram"></i>Instagram</a>
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
<div id="music163player">
|
||
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="450" src="//music.163.com/outchain/player?type=4&id=334277093&auto=1&height=430"></iframe>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!--noindex-->
|
||
<section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
|
||
<div class="post-toc">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#0x00-背景与简介"><span class="nav-text">0x00 背景与简介</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#REF"><span class="nav-text">REF</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#0x01-基础条件"><span class="nav-text">0x01 基础条件</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#0x02-qemu-用户模式"><span class="nav-text">0x02 qemu-用户模式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#模拟miniupnp"><span class="nav-text">模拟miniupnp</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#0x03-qemu-系统模式"><span class="nav-text">0x03 qemu-系统模式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#MIPS系统网络配置"><span class="nav-text">MIPS系统网络配置</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#0x04-在mips虚拟机中调试"><span class="nav-text">0x04 在mips虚拟机中调试</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#0x05-设备上调试程序"><span class="nav-text">0x05 设备上调试程序</span></a></li></ol></div>
|
||
|
||
|
||
</div>
|
||
</section>
|
||
<!--/noindex-->
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</aside>
|
||
|
||
|
||
|
||
</div>
|
||
</main>
|
||
|
||
<footer id="footer" class="footer">
|
||
<div class="footer-inner">
|
||
<div class="copyright">© <span itemprop="copyrightYear">2019</span>
|
||
<span class="with-love">
|
||
<i class="fa fa-user"></i>
|
||
</span>
|
||
<span class="author" itemprop="copyrightHolder">Cool-Y</span>
|
||
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-area-chart"></i>
|
||
</span>
|
||
|
||
<span title="Site words total count">72k</span>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="busuanzi-count">
|
||
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
|
||
|
||
|
||
<span class="site-uv">
|
||
<i class="fa fa-user"></i>
|
||
<span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="site-pv">
|
||
<i class="fa fa-eye"></i>
|
||
<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
|
||
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
|
||
<div class="back-to-top">
|
||
<i class="fa fa-arrow-up"></i>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
|
||
window.Promise = null;
|
||
}
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>
|
||
|
||
<script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>
|
||
|
||
<script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
|
||
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<!-- LOCAL: You can save these files to your site and update links -->
|
||
|
||
|
||
<link rel="stylesheet" href="https://jjeejj.github.io/css/gitment.css">
|
||
<script src="https://jjeejj.github.io/js/gitment.js"></script>
|
||
|
||
<!-- END LOCAL -->
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
function renderGitment(){
|
||
var gitment = new Gitment({
|
||
id: window.location.pathname,
|
||
owner: 'Cool-Y',
|
||
repo: 'gitment-comments',
|
||
|
||
oauth: {
|
||
|
||
|
||
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
|
||
|
||
client_id: '180955a2c3ae3d966d9a'
|
||
}});
|
||
gitment.render('gitment-container');
|
||
}
|
||
|
||
|
||
renderGitment();
|
||
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
// Popup Window;
|
||
var isfetched = false;
|
||
var isXml = true;
|
||
// Search DB path;
|
||
var search_path = "search.xml";
|
||
if (search_path.length === 0) {
|
||
search_path = "search.xml";
|
||
} else if (/json$/i.test(search_path)) {
|
||
isXml = false;
|
||
}
|
||
var path = "/" + search_path;
|
||
// monitor main search box;
|
||
|
||
var onPopupClose = function (e) {
|
||
$('.popup').hide();
|
||
$('#local-search-input').val('');
|
||
$('.search-result-list').remove();
|
||
$('#no-result').remove();
|
||
$(".local-search-pop-overlay").remove();
|
||
$('body').css('overflow', '');
|
||
}
|
||
|
||
function proceedsearch() {
|
||
$("body")
|
||
.append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
|
||
.css('overflow', 'hidden');
|
||
$('.search-popup-overlay').click(onPopupClose);
|
||
$('.popup').toggle();
|
||
var $localSearchInput = $('#local-search-input');
|
||
$localSearchInput.attr("autocapitalize", "none");
|
||
$localSearchInput.attr("autocorrect", "off");
|
||
$localSearchInput.focus();
|
||
}
|
||
|
||
// search function;
|
||
var searchFunc = function(path, search_id, content_id) {
|
||
'use strict';
|
||
|
||
// start loading animation
|
||
$("body")
|
||
.append('<div class="search-popup-overlay local-search-pop-overlay">' +
|
||
'<div id="search-loading-icon">' +
|
||
'<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
|
||
'</div>' +
|
||
'</div>')
|
||
.css('overflow', 'hidden');
|
||
$("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');
|
||
|
||
$.ajax({
|
||
url: path,
|
||
dataType: isXml ? "xml" : "json",
|
||
async: true,
|
||
success: function(res) {
|
||
// get the contents from search data
|
||
isfetched = true;
|
||
$('.popup').detach().appendTo('.header-inner');
|
||
var datas = isXml ? $("entry", res).map(function() {
|
||
return {
|
||
title: $("title", this).text(),
|
||
content: $("content",this).text(),
|
||
url: $("url" , this).text()
|
||
};
|
||
}).get() : res;
|
||
var input = document.getElementById(search_id);
|
||
var resultContent = document.getElementById(content_id);
|
||
var inputEventFunction = function() {
|
||
var searchText = input.value.trim().toLowerCase();
|
||
var keywords = searchText.split(/[\s\-]+/);
|
||
if (keywords.length > 1) {
|
||
keywords.push(searchText);
|
||
}
|
||
var resultItems = [];
|
||
if (searchText.length > 0) {
|
||
// perform local searching
|
||
datas.forEach(function(data) {
|
||
var isMatch = false;
|
||
var hitCount = 0;
|
||
var searchTextCount = 0;
|
||
var title = data.title.trim();
|
||
var titleInLowerCase = title.toLowerCase();
|
||
var content = data.content.trim().replace(/<[^>]+>/g,"");
|
||
var contentInLowerCase = content.toLowerCase();
|
||
var articleUrl = decodeURIComponent(data.url);
|
||
var indexOfTitle = [];
|
||
var indexOfContent = [];
|
||
// only match articles with not empty titles
|
||
if(title != '') {
|
||
keywords.forEach(function(keyword) {
|
||
function getIndexByWord(word, text, caseSensitive) {
|
||
var wordLen = word.length;
|
||
if (wordLen === 0) {
|
||
return [];
|
||
}
|
||
var startPosition = 0, position = [], index = [];
|
||
if (!caseSensitive) {
|
||
text = text.toLowerCase();
|
||
word = word.toLowerCase();
|
||
}
|
||
while ((position = text.indexOf(word, startPosition)) > -1) {
|
||
index.push({position: position, word: word});
|
||
startPosition = position + wordLen;
|
||
}
|
||
return index;
|
||
}
|
||
|
||
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
|
||
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
|
||
});
|
||
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
|
||
isMatch = true;
|
||
hitCount = indexOfTitle.length + indexOfContent.length;
|
||
}
|
||
}
|
||
|
||
// show search results
|
||
|
||
if (isMatch) {
|
||
// sort index by position of keyword
|
||
|
||
[indexOfTitle, indexOfContent].forEach(function (index) {
|
||
index.sort(function (itemLeft, itemRight) {
|
||
if (itemRight.position !== itemLeft.position) {
|
||
return itemRight.position - itemLeft.position;
|
||
} else {
|
||
return itemLeft.word.length - itemRight.word.length;
|
||
}
|
||
});
|
||
});
|
||
|
||
// merge hits into slices
|
||
|
||
function mergeIntoSlice(text, start, end, index) {
|
||
var item = index[index.length - 1];
|
||
var position = item.position;
|
||
var word = item.word;
|
||
var hits = [];
|
||
var searchTextCountInSlice = 0;
|
||
while (position + word.length <= end && index.length != 0) {
|
||
if (word === searchText) {
|
||
searchTextCountInSlice++;
|
||
}
|
||
hits.push({position: position, length: word.length});
|
||
var wordEnd = position + word.length;
|
||
|
||
// move to next position of hit
|
||
|
||
index.pop();
|
||
while (index.length != 0) {
|
||
item = index[index.length - 1];
|
||
position = item.position;
|
||
word = item.word;
|
||
if (wordEnd > position) {
|
||
index.pop();
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
searchTextCount += searchTextCountInSlice;
|
||
return {
|
||
hits: hits,
|
||
start: start,
|
||
end: end,
|
||
searchTextCount: searchTextCountInSlice
|
||
};
|
||
}
|
||
|
||
var slicesOfTitle = [];
|
||
if (indexOfTitle.length != 0) {
|
||
slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
|
||
}
|
||
|
||
var slicesOfContent = [];
|
||
while (indexOfContent.length != 0) {
|
||
var item = indexOfContent[indexOfContent.length - 1];
|
||
var position = item.position;
|
||
var word = item.word;
|
||
// cut out 100 characters
|
||
var start = position - 20;
|
||
var end = position + 80;
|
||
if(start < 0){
|
||
start = 0;
|
||
}
|
||
if (end < position + word.length) {
|
||
end = position + word.length;
|
||
}
|
||
if(end > content.length){
|
||
end = content.length;
|
||
}
|
||
slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
|
||
}
|
||
|
||
// sort slices in content by search text's count and hits' count
|
||
|
||
slicesOfContent.sort(function (sliceLeft, sliceRight) {
|
||
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
|
||
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
|
||
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
|
||
return sliceRight.hits.length - sliceLeft.hits.length;
|
||
} else {
|
||
return sliceLeft.start - sliceRight.start;
|
||
}
|
||
});
|
||
|
||
// select top N slices in content
|
||
|
||
var upperBound = parseInt('1');
|
||
if (upperBound >= 0) {
|
||
slicesOfContent = slicesOfContent.slice(0, upperBound);
|
||
}
|
||
|
||
// highlight title and content
|
||
|
||
function highlightKeyword(text, slice) {
|
||
var result = '';
|
||
var prevEnd = slice.start;
|
||
slice.hits.forEach(function (hit) {
|
||
result += text.substring(prevEnd, hit.position);
|
||
var end = hit.position + hit.length;
|
||
result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
|
||
prevEnd = end;
|
||
});
|
||
result += text.substring(prevEnd, slice.end);
|
||
return result;
|
||
}
|
||
|
||
var resultItem = '';
|
||
|
||
if (slicesOfTitle.length != 0) {
|
||
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
|
||
} else {
|
||
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
|
||
}
|
||
|
||
slicesOfContent.forEach(function (slice) {
|
||
resultItem += "<a href='" + articleUrl + "'>" +
|
||
"<p class=\"search-result\">" + highlightKeyword(content, slice) +
|
||
"...</p>" + "</a>";
|
||
});
|
||
|
||
resultItem += "</li>";
|
||
resultItems.push({
|
||
item: resultItem,
|
||
searchTextCount: searchTextCount,
|
||
hitCount: hitCount,
|
||
id: resultItems.length
|
||
});
|
||
}
|
||
})
|
||
};
|
||
if (keywords.length === 1 && keywords[0] === "") {
|
||
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
|
||
} else if (resultItems.length === 0) {
|
||
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
|
||
} else {
|
||
resultItems.sort(function (resultLeft, resultRight) {
|
||
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
|
||
return resultRight.searchTextCount - resultLeft.searchTextCount;
|
||
} else if (resultLeft.hitCount !== resultRight.hitCount) {
|
||
return resultRight.hitCount - resultLeft.hitCount;
|
||
} else {
|
||
return resultRight.id - resultLeft.id;
|
||
}
|
||
});
|
||
var searchResultList = '<ul class=\"search-result-list\">';
|
||
resultItems.forEach(function (result) {
|
||
searchResultList += result.item;
|
||
})
|
||
searchResultList += "</ul>";
|
||
resultContent.innerHTML = searchResultList;
|
||
}
|
||
}
|
||
|
||
if ('auto' === 'auto') {
|
||
input.addEventListener('input', inputEventFunction);
|
||
} else {
|
||
$('.search-icon').click(inputEventFunction);
|
||
input.addEventListener('keypress', function (event) {
|
||
if (event.keyCode === 13) {
|
||
inputEventFunction();
|
||
}
|
||
});
|
||
}
|
||
|
||
// remove loading animation
|
||
$(".local-search-pop-overlay").remove();
|
||
$('body').css('overflow', '');
|
||
|
||
proceedsearch();
|
||
}
|
||
});
|
||
}
|
||
|
||
// handle and trigger popup window;
|
||
$('.popup-trigger').click(function(e) {
|
||
e.stopPropagation();
|
||
if (isfetched === false) {
|
||
searchFunc(path, 'local-search-input', 'local-search-result');
|
||
} else {
|
||
proceedsearch();
|
||
};
|
||
});
|
||
|
||
$('.popup-btn-close').click(onPopupClose);
|
||
$('.popup').click(function(e){
|
||
e.stopPropagation();
|
||
});
|
||
$(document).on('keyup', function (event) {
|
||
var shouldDismissSearchPopup = event.which === 27 &&
|
||
$('.search-popup').is(':visible');
|
||
if (shouldDismissSearchPopup) {
|
||
onPopupClose();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
|
||
<script>AV.initialize("EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz", "x8FxDrYG79C8YFrTww9ljo8K");</script>
|
||
<script>
|
||
function showTime(Counter) {
|
||
var query = new AV.Query(Counter);
|
||
var entries = [];
|
||
var $visitors = $(".leancloud_visitors");
|
||
|
||
$visitors.each(function () {
|
||
entries.push( $(this).attr("id").trim() );
|
||
});
|
||
|
||
query.containedIn('url', entries);
|
||
query.find()
|
||
.done(function (results) {
|
||
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
|
||
|
||
if (results.length === 0) {
|
||
$visitors.find(COUNT_CONTAINER_REF).text(0);
|
||
return;
|
||
}
|
||
|
||
for (var i = 0; i < results.length; i++) {
|
||
var item = results[i];
|
||
var url = item.get('url');
|
||
var time = item.get('time');
|
||
var element = document.getElementById(url);
|
||
|
||
$(element).find(COUNT_CONTAINER_REF).text(time);
|
||
}
|
||
for(var i = 0; i < entries.length; i++) {
|
||
var url = entries[i];
|
||
var element = document.getElementById(url);
|
||
var countSpan = $(element).find(COUNT_CONTAINER_REF);
|
||
if( countSpan.text() == '') {
|
||
countSpan.text(0);
|
||
}
|
||
}
|
||
})
|
||
.fail(function (object, error) {
|
||
console.log("Error: " + error.code + " " + error.message);
|
||
});
|
||
}
|
||
|
||
function addCount(Counter) {
|
||
var $visitors = $(".leancloud_visitors");
|
||
var url = $visitors.attr('id').trim();
|
||
var title = $visitors.attr('data-flag-title').trim();
|
||
var query = new AV.Query(Counter);
|
||
|
||
query.equalTo("url", url);
|
||
query.find({
|
||
success: function(results) {
|
||
if (results.length > 0) {
|
||
var counter = results[0];
|
||
counter.fetchWhenSave(true);
|
||
counter.increment("time");
|
||
counter.save(null, {
|
||
success: function(counter) {
|
||
var $element = $(document.getElementById(url));
|
||
$element.find('.leancloud-visitors-count').text(counter.get('time'));
|
||
},
|
||
error: function(counter, error) {
|
||
console.log('Failed to save Visitor num, with error message: ' + error.message);
|
||
}
|
||
});
|
||
} else {
|
||
var newcounter = new Counter();
|
||
/* Set ACL */
|
||
var acl = new AV.ACL();
|
||
acl.setPublicReadAccess(true);
|
||
acl.setPublicWriteAccess(true);
|
||
newcounter.setACL(acl);
|
||
/* End Set ACL */
|
||
newcounter.set("title", title);
|
||
newcounter.set("url", url);
|
||
newcounter.set("time", 1);
|
||
newcounter.save(null, {
|
||
success: function(newcounter) {
|
||
var $element = $(document.getElementById(url));
|
||
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
|
||
},
|
||
error: function(newcounter, error) {
|
||
console.log('Failed to create');
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function(error) {
|
||
console.log('Error:' + error.code + " " + error.message);
|
||
}
|
||
});
|
||
}
|
||
|
||
$(function() {
|
||
var Counter = AV.Object.extend("Counter");
|
||
if ($('.leancloud_visitors').length == 1) {
|
||
addCount(Counter);
|
||
} else if ($('.post-title-link').length > 1) {
|
||
showTime(Counter);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script>
|
||
(function(){
|
||
var bp = document.createElement('script');
|
||
var curProtocol = window.location.protocol.split(':')[0];
|
||
if (curProtocol === 'https') {
|
||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||
}
|
||
else {
|
||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||
}
|
||
var s = document.getElementsByTagName("script")[0];
|
||
s.parentNode.insertBefore(bp, s);
|
||
})();
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|