ubuntu 16.04 安卓 4.4.4编译 + 调试

 先更新

apt update -y && apt upgrade -y
sudo apt-get install libreadline6-dev:i386 libgl1-mesa-dev g++-multilib    tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386    dpkg-dev libsdl1.2-dev libesd0-dev   git-core gnupg flex bison gperf build-essential libgl1-mesa-dev  zip curl zlib1g-dev gcc-multilib g++-multilib    libc6-dev-i386    lib32ncurses5-dev x11proto-core-dev libx11-dev    lib32z-dev ccache   libgl1-mesa-dev libxml2-utils xsltproc unzip m4 android-tools-adb -y

 

java安装

mkdir  /usr/java

jdk-6u45-linux-x64.bin 放置到 /usr/java 安卓4.4.4必须使用oracle jdk 1.6

/usr/java目录下 执行 jdk-6u45-linux-x64.bin

export JAVA_HOME=/usr/java/jdk1.6.0_45
export JAVA_BIN=/usr/java/jdk1.6.0_45/bin
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JAVA_BIN PATH CLASSPATH
source /etc/profile

修改后生效一下

下载源码

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
mkdir android
cd android
git config --global user.name "k4n5ha0"
git config --global user.email "k4n5ha0@qq.com"
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-4.4.4_r2
repo sync --no-tags --no-clone-bundle            //开始下载代码
#!/bin/sh
repo sync
while [ $? -ne 0 ]
do
repo sync
done

sh myrepo.sh  可以保持重试

安装make

ubuntu16.04自带的make版本过高,无法编译。因此需要将make降至3.82.

下载地址ftp://ftp.gnu.org/gnu/make/

下载后到Downloads下将文件拷到其他目录(home下即可),然后解压

tar -zxvf make3.8.2.tar.gz

解压后进入到make3.8.2的目录下

./configure
make
sudo make install

执行完后在/usr/local/bin中可得到新版本的make,复制到/usr/bin中即可

seven@ThinkPad:/usr/local/bin$ sudo mv make /usr/bin

注:make过程中可能会出现错误,不用理会,只要make install能够成功执行即可。

安装android device monitor

http://www.androiddevtools.cn/

直接下载  ADT Bundle

运行 /root/adt-bundle-linux-x86_64-20140702/sdk/tools/monitor

作为调试用的ddms

编译开始

lunch  //选择你的编译版本
echo export USE_CCACHE=1 >> ~/.bashrc
prebuilts/misc/linux-x86/ccache/ccache -M 50G
source build/envsetup.sh
lunch
make -j8

执行

source build/envsetup.sh && lunch && emulator -memory 1024

增加点内存

调大运行ram

dumpsys meminfo 

这条命令在adb shell 后可以查看安卓内存使用

别忘记开启虚这个安卓的usb调试 mtp设备 否则会被当成是usb的储存设备

当然还是要开启安装未知源的选项,不过奇怪的是必须重启才生效

/////////////

如果出现错误  error: do_inode_allocate_extents: Failed to allocate 12275 blocks

"/root/android/build/target/board/generic_x86/BoardConfig.mk"

修改上面路径的文件  修改 BOARD_SYSTEMIMAGE_PARTITION_SIZE 这个参数为如下代码

BOARD_SYSTEMIMAGE_PARTITION_SIZE := 524288000 

如果要调试的app体积很大,需要将这个值增大

/////////////

编译kernel 我们使用3.4的内核

注意:我们要在 安卓源码主目录 

#/root/android/ 作为主目录
git clone  https://android.googlesource.com/kernel/goldfish.git
cd goldfish/
git branch -a  
git checkout android-goldfish-3.4

#注意要选中内核目标版本
#然后切换到 安卓主目录
#/root/android/ 目录下
source build/envsetup.sh
lunch
cd /root/android/goldfish
#进入kernel目录后 然后编译内核
/root/android/external/qemu/distrib/build-kernel.sh

提示成功如下!!!!!!
Kernel goldfish_armv7 copied to /tmp/kernel-qemu successfully !

#如此执行虚拟机
#cd /root/android/
source build/envsetup.sh
lunch
emulator -kernel /tmp/kernel-qemu/kernel-qemu-armv7 -memory 1024
我们把目录转移一下
emulator -kernel /root/android/kernel-qemu/kernel-qemu-armv7

#我们就搞个  ango.sh在 安卓主目录下

#!/bin/bash
source build/envsetup.sh && lunch
emulator -kernel /root/android/kernel-qemu/kernel-qemu-armv7

/////////////

防止TracerPid反调试

/root/android/goldfish/fs/proc/array.c

做如下修改

static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;
	const struct cred *cred;
	pid_t ppid, tpid;

	rcu_read_lock();
	ppid = pid_alive(p) ?
		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
	tpid = 0;
	if (pid_alive(p)) {
		struct task_struct *tracer = ptrace_parent(p);
		if (tracer)
			tpid = task_pid_nr_ns(tracer, ns);
	}
	tpid = 0;  //保证TracerPid为0
	cred = get_task_cred(p);
	seq_printf(m,
		"State:\t%s\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		//get_task_state(p),  //注释本行
		"S (sleeping)",         //强制为sleep的进程状态
		task_tgid_nr_ns(p, ns),
		pid_nr_ns(pid, ns),
		ppid, tpid,
		cred->uid, cred->euid, cred->suid, cred->fsuid,
		cred->gid, cred->egid, cred->sgid, cred->fsgid);

进程状态参考
static const char * const task_state_array[] = {
	"R (running)",		/*   0 */
	"S (sleeping)",		/*   1 */
	"D (disk sleep)",	/*   2 */
	"T (stopped)",		/*   4 */
	"t (tracing stop)",	/*   8 */
	"Z (zombie)",		/*  16 */
	"X (dead)",		/*  32 */
	"x (dead)",		/*  64 */
	"K (wakekill)",		/* 128 */
	"W (waking)",		/* 256 */
};

 

/////////////

防止fork反调试

修改    /root/android/bionic/libc/bionic/fork.c      文件

#include <unistd.h>
#include "pthread_internal.h"
#include "bionic_pthread.h"
#include "cpuacct.h"
#include <fcntl.h>  //必须增加这个头文件!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#define BUF_LENTH 1000   //必须增加这个参数!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

extern int  __fork(void);

// 进行脱壳apk进程的过滤  
int is_target_apk_pid()   
{  
    char szBuffer[BUF_LENTH] = {0};  
    char szCmd[BUF_LENTH] = {0};  
      
    // 格式化字符串得到/proc/pid/cmdline  
    sprintf(szCmd, "/proc/%d/cmdline", getpid());  
      
    // 获取当前pid进程的文件名称字符串(比较粗糙)  
    int fd = open(szCmd, O_RDONLY);  
    if (read(fd, szBuffer, BUF_LENTH))   
    {  
        //......  
    }  
    else   
    {  
        //......  
    }  
    close(fd);  
      
    // 判断当前pid进程是否是需要的过滤的脱壳apk进程  
    //memset(szCmd, 0, sizeof(szCmd));  
    //sprintf(szCmd,"/data/data/%s", szBuffer);  
    if (strstr(szBuffer, "com.jianbao"))   //要监控的进程名字!!!!!!!!!!!!!!!!!!!!!
    {  
        return 1;  
    }  
      
    return 0;  
}  

int  fork(void)
{
    int  ret;
	if (is_target_apk_pid())  
    {  
        return -1;  
    }  
    /* Posix mandates that the timers of a fork child process be
     * disarmed, but not destroyed. To avoid a race condition, we're
     * going to stop all timers now, and only re-start them in case
     * of error, or in the parent process
     */
    __timer_table_start_stop(1);
    __bionic_atfork_run_prepare();

    ret = __fork();
    if (ret != 0) {  /* not a child process */
        __timer_table_start_stop(0);
        __bionic_atfork_run_parent();
    } else {
        // Fix the tid in the pthread_internal_t struct after a fork.
        __pthread_settid(pthread_self(), gettid());

        /*
         * Newly created process must update cpu accounting.
         * Call cpuacct_add passing in our uid, which will take
         * the current task id and add it to the uid group passed
         * as a parameter.
         */
        cpuacct_add(getuid());
        __bionic_atfork_run_child();
    }
    return ret;
}

///////////////////////

此方法证明干扰ida调试 请勿修改!

/root/android/dalvik/vm/native/dalvik_system_VMDebug.cpp

修改Debug.isDebuggerConnected 反调试

static void Dalvik_dalvik_system_VMDebug_isDebuggerConnected(const u4* args,
    JValue* pResult)
{
    UNUSED_PARAMETER(args);

    //RETURN_BOOLEAN(dvmDbgIsDebuggerConnected()); 注释这行 修改为下一行
	RETURN_BOOLEAN(false);
}

//////////////////////

增加ida调试断点

修改 此文件 "/root/android/dalvik/vm/Native.cpp"

version = (*func)(gDvmJni.jniVm, NULL);

之前加入        

ALOGI("JNI_OnLoad!!!!!!!!!!!!");

在调试的时候直接在ida中 按G

让 libdvm.so 基地址加上 0x4FDE0 就是这个地址 如果你熟悉了

 0x4FDE0直接用 模块基地址 减去

ALOGI("JNI_OnLoad!!!!!!!!!!!!");地址之后的BLX之前的地址算一下就能得出很简单

shift + f7能看到加载的基地址

直接在 ida里面搜索jni_Onload字符串就能找到对应的地址

f5状态下 按tab键 就能切换到对应的汇编代码

之后就是对应的地址减去基地址就行了

///////////////////////

双机调试设置 注意执行顺序!

ubuntu上

adb forward tcp:23946 tcp:12345

安卓上

/data/local/tmp/android_server -p12345 &
防止壳检测 把名字改一改
/data/local/tmp/com.360 -p12345

windows上

使用MobaXterm

130854_6B1c_2897384.png

其中10.10.12.76就是ubuntu机

这样ida 附加调试就能断下来

130936_Siij_2897384.png

以调试模式启动应用

使用AndroidKiller打开APK文件进行反编译,可以看到文件的包名和入口
160753_aL1H_2897384.png

adb shell am start -D -n longbin.helloworld/longbin.helloworld.SplashActivity

就可以ida附加了  附加的参数要如下设置

171949_xxcx_2897384.png

 

f5状态下 按tab键 就能切换到对应的汇编代码

在ubuntu下面打开ddms要做一下设置

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.200.v20120913-144807
-data
@noDefault
-vmargs
-XX:MaxPermSize=256m
-Xms512m
-Xmx1024m

修改为

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.200.v20120913-144807
-data
@noDefault
-vm
/root/android-studio/jre/bin/java
-vmargs
-XX:MaxPermSize=256m
-Xms512m
-Xmx1024m

也就是增加一下jre路径

///////////////

启动ddms 

执行一下adb shell

启动虚拟机   

进入adb shell  后     

/data/local/tmp/com.360 -p12345

执行

adb forward tcp:23946 tcp:12345  

adb shell am start -D -n com.jianbao.doctor/com.jianbao.doctor.activity.SplashActivity

然后ida附加  并且下断点

之后执行

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

两个小脚本

#!/bin/bash
/root/adt-bundle-linux-x86_64-20140702/sdk/tools/monitor

-->启动ddms的

#!/bin/bash
source build/envsetup.sh && lunch
emulator -kernel /root/android/kernel-qemu/kernel-qemu-armv7

-->启动虚拟机的

执行如下py脚本自动会断在jni_Onload载入前的关键BLX 我用了硬地址 

硬地址直接用 BLX的地址转换成10进制就能得出327150  很简单

import idautils
import idc
import idaapi

def main():
    # begin to locate libdvm.so module base
    
    has_art = False
    module_base = GetFirstModule()
    while module_base != None:
        module_name = GetModuleName(module_base)
        if module_name.find('libdvm.so') >= 0:
            has_art = True
            break
        
        module_base = GetNextModule(module_base)
    
    if has_art == False:
        print '[*]unable to find libdvm.so module base'
        return
    
    module_size = GetModuleSize(module_base)
    blx_r12_ea = 0
    print '[*]found libdvm.so base=>0x%08X, Size=0x%08X' % (module_base, module_size)
    print("[-]begin to search JNI_OnLoad")
    print "[-]found string JNI_OnLoad BLX R12 addr=>0x%X" % (module_base + 327150)
    AddBpt(module_base + 327150)
    print("[*]script by SexyBoy, enjoy~~")
main()

 

转载于:https://my.oschina.net/9199771/blog/1551253

<think>好的,我现在需要帮助用户在Ubuntu 16.04上安装Clang++ 14。首先,用户提供的引用资料里提到了一些关于安装Clang不同版本的信息,但都是关于较旧版本的,比如3.6或者通过apt安装的默认版本。而用户需要的是Clang++ 14,这是一个比较新的版本,而Ubuntu 16.04的官方仓库可能没有直接支持。 首先,我应该考虑Ubuntu 16.04的软件源是否包含Clang 14。根据经验,Ubuntu的官方仓库通常不会提供太新的软件版本,尤其是对于已经停止支持的发行版。Ubuntu 16.042021年4月已经结束了标准支持,所以很可能需要第三方源或者手动安装。 接下来,查看用户提供的引用内容,引用[2]和[3]提到在Ubuntu 16.04下通过apt安装clang-format和clang,但版本可能较低。比如引用[3]中安装的是clang和clangd,但没有说明具体版本,可能默认是系统仓库里的旧版。因此,我需要寻找其他方法。 一种常见的方法是使用LLVM的官方APT仓库。LLVM提供了不同版本的预编译包,可能支持旧版Ubuntu。用户需要添加LLVM的APT源,然后安装Clang 14。但需要确认该仓库是否支持Ubuntu 16.04(代号Xenial)。可能需要检查LLVM官网的说明。 另外,如果官方仓库不支持,可能需要手动下载Clang 14的二进制文件或者从源码编译。但编译源码对用户来说可能比较复杂,特别是如果用户不熟悉构建过程的话。所以优先考虑添加第三方源。 现在,我应该指导用户添加LLVM的APT仓库。通常步骤是: 1. 下载并安装LLVM的GPG密钥。 2. 添加仓库地址到sources.list。 3. 更新软件包列表。 4. 安装clang-14。 但需要确认该仓库是否支持Xenial。例如,LLVM的APT仓库可能只支持较新的Ubuntu版本。如果不行,可能需要使用其他方法,比如使用Ubuntu Toolchain PPA,或者通过snap安装。 另外,用户可能需要安装libstdc++或libc++,如引用[4]所述,但Clang 14可能需要更高版本的库,可能需要处理依赖关系。 可能的步骤: 1. 添加LLVM的APT仓库,如果支持Xenial的话。 2. 安装Clang 14及相关工具。 3. 处理可能的依赖问题,比如libstdc++的版本。 但需要验证Xenial是否在LLVM的APT支持列表中。例如,访问https://apt.llvm.org/查看支持的发行版。假设Xenial不在其中,那么可能需要手动安装。 另一种方法是使用预编译的二进制文件。从releases.llvm.org下载Clang 14的二进制包,解压并添加到PATH中。这可能需要用户手动设置环境变量,或者使用符号链接。 例如: wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz 解压后,将bin目录加入PATH。 但需要注意,该二进制是否适用于Ubuntu 16.04,可能依赖的库版本是否满足。如果二进制是针对Ubuntu 18.04构建的,可能在16.04上运行时出现glibc版本不兼容的问题。例如,Ubuntu 16.04的glibc版本是2.23,而18.04的是2.27,如果Clang 14需要更高版本的glibc,则无法运行。 这时可能需要考虑从源码编译Clang 14,但编译过程较为复杂,特别是对于不熟悉的用户来说可能有困难。 还有一种可能,使用第三方PPA,比如Ubuntu Toolchain的测试仓库,但需要检查是否有Clang 14的PPA支持Xenial。 总结可能的步骤: - 尝试通过LLVM的APT仓库安装,如果支持。 - 如果不行,尝试下载预编译的二进制文件,检查依赖。 - 若依赖不满足,考虑源码编译或使用其他方法。 现在,我需要根据这些可能性,给出用户一个可行的步骤。假设用户无法通过APT安装,那么手动下载预编译的二进制可能是更简单的方式,但需要处理依赖问题。或者建议用户升级到更高版本的Ubuntu以获得更好的支持。 在用户提供的引用中,引用[1]提到在Ubuntu上安装clang++3.6时遇到问题,但用户需要的是14版本,所以可能需要不同的方法。引用[4]提到libc++和libstdc++的区别,可能需要安装对应的库。 因此,步骤可能包括: 1. 添加LLVM的APT仓库: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo add-apt-repository 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-14 main' sudo apt update sudo apt install clang-14 但需要确认该仓库是否存在xenial的版本。例如,访问https://apt.llvm.org/,查看是否有针对Xenial的14版本。假设存在的话,可以继续。 如果不存在,可能需要修改为其他代号,比如用bionic(18.04)的仓库,但可能不兼容。 比如,尝试使用: deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial main deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-14 main 但不确定是否存在该仓库。如果不存在,则这种方法不可行。 如果无法通过APT安装,则考虑手动下载二进制包: 从https://releases.llvm.org/download.html#14.0.0下载适用于Ubuntu的预编译版本,例如选择Clang 14.0.0的Pre-Built Binaries: x86_64-linux-gnu-ubuntu-18.04,解压后设置环境变量。 但需要检查glibc的版本: 在Ubuntu 16.04终端运行: ldd --version 如果输出显示glibc 2.23,而预编译的二进制可能需要更高版本,则无法运行。例如,Ubuntu 18.04的glibc是2.27,所以Clang 14的二进制可能需要glibc >=2.27,导致无法在16.04上运行。 这时可能需要从源码编译Clang,或者使用Docker容器等其他方法。 如果用户坚持在Ubuntu 16.04上安装,可能需要编译Clang 14的源码。步骤如下: 安装依赖: sudo apt update sudo apt install build-essential cmake ninja-build git 下载源码: git clone https://github.com/llvm/llvm-project.git cd llvm-project git checkout release/14.x 编译: mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" ../llvm make -j$(nproc) sudo make install 这个过程可能需要较长时间,且可能出现依赖问题,需要处理。 因此,综合来看,可能的解决方案包括: 1. 添加LLVM官方APT仓库,如果支持Xenial。 2. 使用预编译的二进制(可能不兼容)。 3. 从源码编译4. 建议升级Ubuntu版本或使用Docker。 现在需要根据用户的情况给出建议。如果用户无法升级系统,可能需要源码编译。如果用户愿意使用其他方法,可能更简单。 最终,回答应分步骤指导用户如何安装,可能包括APT方法(如果可行),或手动安装方法,并指出可能的依赖问题。</think>要在Ubuntu 16.04上安装Clang++ 14,由于该版本已结束官方支持且软件仓库未提供Clang 14,需通过以下步骤手动安装: --- ### **方法1:使用LLVM官方APT仓库(若支持)** 1. **添加LLVM仓库密钥** 执行以下命令添加GPG密钥: ```bash wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - ``` 2. **添加仓库地址** 创建新的源文件(需确认仓库是否支持`xenial`): ```bash sudo nano /etc/apt/sources.list.d/llvm.list ``` 添加以下内容(若仓库支持): ```plaintext deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-14 main ``` 3. **更新并安装** ```bash sudo apt update sudo apt install clang-14 ``` 若仓库不可用,需改用其他方法。 --- ### **方法2:手动安装预编译二进制** 1. **下载二进制包** 从[LLVM官网](https://releases.llvm.org/download.html#14.0.0)下载适用于Linux的Clang 14编译包(如`clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz`): ```bash wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz ``` 2. **解压并配置环境** ```bash tar xvf clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz sudo mv clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04 /opt/clang14 echo 'export PATH="/opt/clang14/bin:$PATH"' >> ~/.bashrc source ~/.bashrc ``` **注意**:若系统依赖库版本过低(如glibc < 2.27),可能无法运行[^4]。 --- ### **方法3:从源码编译(兼容性最佳)** 1. **安装编译依赖** ```bash sudo apt install build-essential cmake ninja-build git ``` 2. **下载源码并编译** ```bash git clone https://github.com/llvm/llvm-project.git cd llvm-project git checkout release/14.x mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" ../llvm make -j$(nproc) sudo make install ``` 此过程耗时较长(约1-2小时),需确保磁盘空间充足。 --- ### **验证安装** 执行以下命令检查版本: ```bash clang++ --version ``` 若输出包含`Clang 14.0.0`,则安装成功。 --- ### **依赖问题处理** - **libstdc++版本过低**:升级GCC或手动安装高版本库。 - **glibc兼容性问题**:若预编译包无法运行,需升级系统或改用源码编译。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值