A. re从零开始的反编译教程
写在开头,引用很喜欢的一句话: 要么学!要么不学!学和不学之间没有中间值 不学就放弃,学就要去认真的学! --致选择
为了回溯编译过程(或对程序进行逆向工程),我们使用各种工具来撤销汇编和编译过程,这些工具就叫反汇编器和反编译器。反汇编器撤销汇编过程,因此我们可以得到汇编语言形式的输出结果。反编译器则以汇编语言甚至是机器语言为输入,其输出结果为高级语言。
数组的表示方式是:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F;对象的表示则以L作为开头,格式是 LpackageName/objectName;
(注意必须有个分号跟在最后),例如String对象在smali中为: Ljava/lang/String; ,其中 java/lang 对应 java.lang 包,String就是定义在该包中的一个对象。或许有人问,既然类是用 LpackageName/objectName; 来表示,那类里面的内部类又如何在smali中引用呢?
答案是:在 LpackageName/objectName/subObjectName 的 subObjectName 前加 $ 符号。
方法的定义一般为: Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type
注意参数与参数之间没有任何分隔符,同样举几个例子就容易明白
无序列表的使用,在符号"-"后加空格使用。如下:
https://www.jianshu.com/p/1c54c1ccf5cc
https://www.cnblogs.com/onelikeone/p/7594177.html
解决:点击进去jd-gui,删除试一试。再不行换最新版本
解析结束后进行编译报错
解决方法: https://blog.csdn.net/fuchaosz/article/details/104800802
Failed parse ring installPackageLI: Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompress
解决方法:
降低gradle里版本,若出现
signatures do not match the previously installed version; ,
使用adb install命令在手机上安装app时,遇到这个报错。原因是新装的app和手机上现有的旧版app冲突了。
解决方法:删除手机上原来的app,再重新安装即可。
可是转念一想如果反编译的apk都是Version 30 R+以上,难道我解压后挨个改一遍gradle?太彻淡了,一定有解决方法,所以有了下面探究出现这个问题的解决方法:既然报错是资源文件高版本不支持,而且没有4位对齐,那么不编译资源文件就好了
APK签名工具之jarsigner和apksigner:
https://blog.csdn.net/xzytl60937234/article/details/89088215?utm_medium=distribute.pc_relevant.none-task-blog-js_landingword-1&spm=1001.2101.3001.4242
利用apktool反编译apk,并且重新签名打包:
https://blog.csdn.net/qq_21007661/article/details/109851522?utm_medium=distribute.pc_relevant.none-task-blog-js_title-4&spm=1001.2101.3001.4242
验证apktool能否使用
apktool -r d apk名字.apk,不反编译资源文件,为什么这么做,先挖个坑
错误提示没有4位对齐和不支持30版本以上的资源文件。所有尝试不编译资源文件
解决4位对齐的方法:
查看当前目录,生成了新文件:abc.keystor
使用JarSigner对apk进行签名,命令如下
jarsigner -verbose -keystore abc.keystore -signedjar testx.apk src.apk abc.keystore
直接反编译的apk产生上述错误
但是只编译资源文件的apk安装时
发现没有使用V2进行签名,这时候进行V2签名, (apksigner,默认同时使用V1和V2签名 )
所以先对只编译资源文件的apk进行V2尝试看能否成功
重复1(进行apktool -r d apk名字.apk)-->2 -->3 -->4( 不使用jarsigner而使用apksigner )
将生成的abc.keystore和打包回的apk( apktoolapp-debugdist 里的app-debug.apk)放入 C:Users aowei.lianAppDataLocalAndroidSdkuild-tools30.0.3 下,因为Android studio的SDK下有apksigner.bat.
对jarsigner只是apk进行了V1签名;在Android7.0引入了V2签名,因此,当进入sdk25.0.0及后续版本,会发现一个apksigner.bat执行脚本。
我们可以通过apksigner进行V2签名,当然,apksigner默认是同时支持V1与V2的,于是:
学习了公钥和密钥的使用和区别,使用私钥的加密算法称为对称加密算法,这种算法实现是接收方和发送方公用一道密钥,优点是效率高,缺点是安全性差,如果被第三人得知密钥则信息泄露,由此衍生了公钥加密算法,也就是非对称加密算法,这个算法是接收方给发送方公钥,发送方用公钥加密后发给接收方,接受方再用私钥解密。这样即使所有人知道公钥也不会造成信息泄露。缺点是效率非常低。
此外了解了RSA签名的大致过程,发送方拥有公钥和私钥,对信息进行摘要然后把摘要通过密钥进行签名,然后把签名和信息一起发出去,那么如何验证该信息就是发送方发出的呢,这时候就使用到了公钥验证,通过公钥对信息进行解签,然后使用一样的摘要算法得到摘要,如果得到的摘要和解签后的内容一致则说明是发送方发出。
总结就是公钥加密,私钥解密。公钥验证,私钥签名
RSA 密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。由公钥加密的内容可以并且只能由私钥进行解密,而由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA 的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。
因为公钥是公开的,任何公钥持有者都可以将想要发送给私钥持有者的信息进行加密后发送,而这个信息只有私钥持有者才能解密。
它和加密有什么区别呢?因为公钥是公开的,所以任何持有公钥的人都能解密私钥加密过的密文,所以这个过程并不能保证消息的安全性,但是它却能保证消息来源的准确性和不可否认性,也就是说,如果使用公钥能正常解密某一个密文,那么就能证明这段密文一定是由私钥持有者发布的,而不是其他第三方发布的,并且私钥持有者不能否认他曾经发布过该消息。故此将该过程称为“签名”。
Android 签名机制 v1、v2、v3
进入JDK/bin, 输入命令
参数:
进入Android SDK/build-tools/SDK版本, 输入命令
参数:
例如:
最后安装加 -t :
附上参考链接:
https://blog.csdn.net/A807296772/article/details/102298970
配置NDK的时候如果按钮是灰色的,手动配置
直接在javac后面指定编码是UTF-8就是了。
需要注意的是要加上* -classpath .其中classpath后面的一个黑点是不能省略的。
编译好后如何导入so库
成功运行后发现lib目录下已经apk编进去so了
https://www.52pojie.cn/thread-732298-1-1.html
本节所有到的工具和Demo
IDA
链接: https://pan..com/s/15uCX8o6tTSSelgG_RN7kBQ
Demo
链接: https://pan..com/s/1vKC1SevvHfeI7f0d2c6IqQ
找到so并打开它 因为我的机型是支持arm的所以我这里打开的是armeabi文件夹下的so 如果机型是x86模式的那么这里要打开x86模式下的libJniTest.so
编译过程:
按住键盘组合键 shift + f12 打开字符串窗口 这个窗口将会列举出so中所包含的所有字符串 因为上节课我们只编写了一个字符串 所以这里只有一个hello 52pojie! 如果打开的是x86的so这里还会有一些.so 但是字符串只有这一个
鼠标点在hello 52pojie!字符串上,打开 Hex mp窗口,修改hello 52pojie!对应内存地址的内容
关于字符对应的16进制可以在网络搜索ascii码表 找到字符所对应的16进制
因为我要把hello 52pojie!修改成hello world! 是不是只要找到每个字符所对应的hex修改就好了
这里我看到 hello 52pojie!对应的hex是:68 65 6C 6C 6F 20 35 32 70 6F 6A 69 65 21
我在ascii码表上找到world所对应的十六进制是:77 6F 72 6C 64
所以hello world! 对应的十六进制是:68 65 6C 6C 6F 20 77 6F 72 6C 64 21
注意编辑的时候光标暂停的位置只有先输入字母才能更改成功,修改好后 右键Apply changes应用
退出后保存
此时已经so修改完毕
大功告成,hello 52pojie! --> hello world!
B. 几种java反编译软件的安装以及使用总结
下面是在网上找的几种反编译软件的安装以及使用:
一、JD-JUI
官网下载链接:http://jd.benow.ca/
下载之后解压,
点击“jd-gui.exe”运行:
直接将".jar"文件拖入进去即可查看里边的“.class”文件,如上图所示。
二:Luyten
官网下载链接:https://github.com/deathmarine/Luyten/releases/tag/v0.5.3
点击“luyten-0.5.3.exe”下载,下载之后点击运行,运行后的界面如图所示,同样也是讲“.jar”文件拖入进入即可。
三、在eclipse中安装反编译工具
准备工作:
“jad.exe”下载:https://varaneckas.com/jad/
“net.sf.jadclipse_3.3.0.jar”下载:https://sourceforge.net/projects/jadclipse/files/
jad.exe”下载:
“net.sf.jadclipse_3.3.0.jar”下载:
然后将“net.sf.jadclipse_3.3.0.jar”拷贝到eclipse的plugins目录下,再删除eclipse的configuration目录下“org.eclipse.update”文件,这一步很重要!
重启eclipse,点击window->Preference->Java,你会发现里边多了一个插件“JadClipse”,
选中这个插件,将下图中红圈圈的地方的地址填写为你 “jad.exe”文件的地址
还没有配置完,先不要close,
点击General->Editors->File Associations 后,进入下边的界面
设置.class 文件默认打开方式:
设置.class without source文件的默认打开方式,
需要注意的是,“JadClipse Class File Viewer”这个一开始是没有的,需用添加,如下图所示:
接下来在eclipse中查看反编译后的代码:(这种方法可能不合适,但是能够查看)
新建一个EJB project,右键“import”,选中"EJB JAR file",导入你的jar包,Finish
在项目下找你要查看的反编译的文件即可,如果你遇到了下边的这种情况
关闭这个文件后再次打开,就可以查看了(我的是这样,所以我感觉这个方法不太好,但别的方法又不知道怎么查看):
有错误或者有更好的方法,希望大家在下边留言指出
C. 如何反编译exe文件
反编译exe文件基本上是不可能的,因为反编译过程由很多因素会干扰,反编译过程:
1、检测程序时候加壳了,如果加壳就必须先去壳。
2、去壳后需要猜测程序员采用的是什么编程语言,编程语言有:java/c/c++/c#/vb/VC++等等。
3、猜测到程序员使用的语言后根据编程语言进行汇编,汇编需要考虑到语言中的语法问题,即使是同种语言,一种命令有多种说法,汇编成功率在20%左右。
4、汇编成功后基本就已经到反编译的顶端了,要从汇编程序翻译成源码可能性为1%。
D. 函数产生的社会背景
历史表明,重要数学概念对数学发展的作用是不可估量的,函数概念对数学发展的影响,可以说是贯穿古今、旷日持久、作用非凡,回顾函数概念的历史发展,看一看函数概念不断被精炼、深化、丰富的历史过程,是一件十分有益的事情,它不仅有助于我们提高对函数概念来龙去脉认识的清晰度,而且更能帮助我们领悟数学概念对数学发展,数学学习的巨大作用.
(一)
��马克思曾经认为,函数概念来源于代数学中不定方程的研究.由于罗马时代的丢番图对不定方程已有相当研究,所以函数概念至少在那时已经萌芽.
��自哥白尼的天文学革命以后,运动就成了文艺复兴时期科学家共同感兴趣的问题,人们在思索:既然地球不是宇宙中心,它本身又有自转和公转,那么下降的物体为什么不发生偏斜而还要垂直下落到地球上?行星运行的轨道是椭圆,原理是什么?还有,研究在地球表面上抛射物体的路线、射程和所能达到的高度,以及炮弹速度对于高度和射程的影响等问题,既是科学家的力图解决的问题,也是军事家要求解决的问题,函数概念就是从运动的研究中引申出的一个数学概念,这是函数概念的力学来源.
(二)
��早在函数概念尚未明确提出以前,数学家已经接触并研究了不少具体的函数,比如对数函数、三角函数、双曲函数等等.1673年前后笛卡儿在他的解析几何中,已经注意到了一个变量对于另一个变量的依赖关系,但由于当时尚未意识到需要提炼一般的函数概念,因此直到17世纪后期牛顿、莱布尼兹建立微积分的时候,数学家还没有明确函数的一般意义.
��1673年,莱布尼兹首次使用函数一词表示“幂”,后来他用该词表示曲线上点的横坐标、纵坐标、切线长等曲线上点的有关几何量.由此可以看出,函数一词最初的数学含义是相当广泛而较为模糊的,几乎与此同时,牛顿在微积分的讨论中,使用另一名词“流量”来表示变量间的关系,直到1689年,瑞士数学家约翰·贝努里才在莱布尼兹函数概念的基础上,对函数概念进行了明确定义,贝努里把变量x和常量按任何方式构成的量叫“x的函数”,表示为yx.
��当时,由于连接变数与常数的运算主要是算术运算、三角运算、指数运算和对数运算,所以后来欧拉就索性把用这些运算连接变数x和常数c而成的式子,取名为解析函数,还将它分成了“代数函数”与“超越函数”.
��18世纪中叶,由于研究弦振动问题,达朗贝尔与欧拉先后引出了“任意的函数”的说法.在解释“任意的函数”概念的时候,达朗贝尔说是指“任意的解析式”,而欧拉则认为是“任意画出的一条曲线”.现在看来这都是函数的表达方式,是函数概念的外延.
(三)
��函数概念缺乏科学的定义,引起了理论与实践的尖锐矛盾.例如,偏微分方程在工程技术中有广泛应用,但由于没有函数的科学定义,就极大地限制了偏微分方程理论的建立.1833年至1834年,高斯开始把注意力转向物理学.他在和W·威伯尔合作发明电报的过程中,做了许多关于磁的实验工作,提出了“力与距离的平方成反比例”这个重要的理论,使得函数作为数学的一个独立分支而出现了,实际的需要促使人们对函数的定义进一步研究.
��后来,人们又给出了这样的定义:如果一个量依赖着另一个量,当后一量变化时前一量也随着变化,那么第一个量称为第二个量的函数.“这个定义虽然还没有道出函数的本质,但却把变化、运动注入到函数定义中去,是可喜的进步.”
��在函数概念发展史上,法国数学家富里埃的工作影响最大,富里埃深刻地揭示了函数的本质,主张函数不必局限于解析表达式.1822年,他在名着《热的解析理论》中说,“通常,函数表示相接的一组值或纵坐标,它们中的每一个都是任意的……,我们不假定这些纵坐标服从一个共同的规律;他们以任何方式一个挨一个.”在该书中,他用一个三角级数和的形式表达了一个由不连续的“线”所给出的函数.更确切地说就是,任意一个以2π为周期函数,在〔-π,π〕区间内,可以由
�表示出,其中
��富里埃的研究,从根本上动摇了旧的关于函数概念的传统思想,在当时的数学界引起了很大的震动.原来,在解析式和曲线之间并不存在不可逾越的鸿沟,级数把解析式和曲线沟通了,那种视函数为解析式的观点终于成为揭示函数关系的巨大障碍.
��通过一场争论,产生了罗巴切夫斯基和狄里克莱的函数定义.
��1834年,俄国数学家罗巴切夫斯基提出函数的定义:“x的函数是这样的一个数,它对于每个x都有确定的值,并且随着x一起变化.函数值可以由解析式给出,也可以由一个条件给出,这个条件提供了一种寻求全部对应值的方法.函数的这种依赖关系可以存在,但仍然是未知的.”这个定义建立了变量与函数之间的对应关系,是对函数概念的一个重大发展,因为“对应”是函数概念的一种本质属性与核心部分.
��1837年,德国数学家狄里克莱(Dirichlet)认为怎样去建立x与y之间的关系无关紧要,所以他的定义是:“如果对于x的每一值,y总有完全确定的值与之对应,则y是x的函数.”
��根据这个定义,即使像如下表述的,它仍然被说成是函数(狄里克莱函数):
f(x)= 1���(x为有理数),
0���(x为无理数).
��在这个函数中,如果x由0逐渐增大地取值,则f(x)忽0忽1.在无论怎样小的区间里,f(x)无限止地忽0忽1.因此,它难用一个或几个式子来加以表示,甚至究竟能否找出表达式也是一个问题.但是不管其能否用表达式表示,在狄里克莱的定义下,这个f(x)仍是一个函数.
��狄里克莱的函数定义,出色地避免了以往函数定义中所有的关于依赖关系的描述,以完全清晰的方式为所有数学家无条件地接受.至此,我们已可以说,函数概念、函数的本质定义已经形成,这就是人们常说的经典函数定义.
(四)
��生产实践和科学实验的进一步发展,又引起函数概念新的尖锐矛盾,本世纪20年代,人类开始研究微观物理现象.1930年量子力学问世了,在量子力学中需要用到一种新的函数——δ-函数,
即�ρ(x)= 0,x≠0,
∞,x=0.
且
��δ-函数的出现,引起了人们的激烈争论.按照函数原来的定义,只允许数与数之间建立对应关系,而没有把“∞”作为数.另外,对于自变量只有一个点不为零的函数,其积分值却不等于零,这也是不可想象的.然而,δ-函数确实是实际模型的抽象.例如,当汽车、火车通过桥梁时,自然对桥梁产生压力.从理论上讲,车辆的轮子和桥面的接触点只有一个,设车辆对轨道、桥面的压力为一单位,这时在接触点x=0处的压强是
��P(0)=压力/接触面=1/0=∞.
��其余点x≠0处,因无压力,故无压强,即�P(x)=0.另外,我们知道压强函数的积分等于压力,即
�函数概念就在这样的历史条件下能动地向前发展,产生了新的现代函数定义:若对集合M的任意元素x,总有集合N确定的元素y与之对应,则称在集合M上定义一个函数,记为y=f(x).元素x称为自变元,元素y称为因变元.
��函数的现代定义与经典定义从形式上看虽然只相差几个字,但却是概念上的重大发展,是数学发展道路上的重大转折,近代的泛函分析可以作为这种转折的标志,它研究的是一般集合上的函数关系.
��函数概念的定义经过二百多年来的锤炼、变革,形成了函数的现代定义,应该说已经相当完善了.不过数学的发展是无止境的,函数现代定义的形式并不意味着函数概念发展的历史终结,近二十年来,数学家们又把函数归结为一种更广泛的概念—“关系”.
��设集合X、Y,我们定义X与Y的积集X×Y为
��X×Y={(x,y)|x∈X,y∈Y}.
��积集X×Y中的一子集R称为X与Y的一个关系,若(x,y)∈R,则称x与y有关系R,记为xRy.若(x,y)R,则称x与y无关系.
��现设f是X与Y的关系,即fX×Y,如果(x,y),(x,z)∈f,必有y=z,那么称f为X到Y的函数.在此定义中,已在形式上回避了“对应”的术语,全部使用集合论的语言了.
��从以上函数概念发展的全过程中,我们体会到,联系实际、联系大量数学素材,研究、发掘、拓广数学概念的内涵是何等重要.
E. JAVA反编译软件
由于JAVA语言安全性高、代码优化、跨平台等特性,从1995年5月由SUN公司发布后,迅速取代了很多传统高级语言,占据了企业级网络应用开发等诸多领域的霸主地位。
不过,JAVA最突出的跨平台优势使得它不能被编译成本地代码,而要以中间代码的形式运行在虚拟机环境中,这使得JAVA的反编译要比别的高级语言容易实现,并且反编译的代码经过优化后几乎可以与源代码相媲美。
为了更好地保护知识产权,避免本公司的智力成果轻易被人窃取,开发者有必要对反编译工具深入了解,以便有针对性地采取保护措施。
目前,比较流行的JAVA反编译工具有近30种,其中有三款堪称精品:
一、 应用广泛的JAD
在众多的JAVA反编译工具中,有几种非常着名的工具使用了相同的核心引擎——JAD,其中主要包括:Front End Plus、mDeJava、Decafe Pro、Cavaj Java Decompiler、DJ Java Decompiler、NMI’s Java Class Viewer和国产的JAVA源代码反编译专家。
JAD本身是一个命令行工具,没有图形界面,上述的这些工具大多是在JAD内核的基础之上加了一个图形界面而已。这么多种产品的共同选择,足可证明JAD在JAVA反编译领域中的尊贵地位。
JAD是使用Microsoft Visual C++开发的,运行速度非常快,可以处理很复杂的JAVA编译文件。众多的参数使JAD可以灵活应付多种加密手段,令反编译的代码更加优化和易读。由于JAD参数太多,没必要一一解释,其中有几个最常用的如下(以JAD 1.5.8f版本为例):
-d
- 用于指定输出文件的目录
-s - 输出文件扩展名(默认为: .jad),通常都会把输出文件扩展名直接指定为.java,以方便修改的重新编译。
-8 - 将Unicode字符转换为ANSI字符串,如果输出字符串是中文的话一定要加上这个参数才能正确显示。
最常用的反编译指令如下所示:
Jad –d c:\javasource –s .java -8 javatest.class
这条指令将当前目录下的javatest.class反编译为javatest.java并保存在c:\javasource目录里,其中的提示输出为中文,而不是Unicode代码。
二、 源码开放的JODE
JODE是全球最大的开源项目网站Sourceforge.net的成员,在所有的JAVA反编译器中,JODE的反编译效果是最好的,尤其是对付一些常见的加密手段,例如混淆技术等,更是出类拔粹。
JODE本身也是纯JAVA开发的,最近越来越多的JAVA反编译软件也选择JODE来做它们的核心引擎,例如JCavaj Java Decompiler、BTJ (Back To Java)、jEdit’s JavaInsight plugin等。
JODE是一个可运行的JAR文件,在windows环境下双击即可运行。
需要特别说明的是,JODE不是通过常规的Open->File的方式来加载JAVA编译后的类文件(*.class)或是类包(*.jar)的, 而是通过在Options菜单中的Set Classpath来实现的,单独的类文件可以将它的上一级目录作为Classpath输入,然后再选择Reload Classpath即可。
新加入的类包或是类的名字会在左侧窗口出现,双击类包名可以展开目录树结构,双击需要反编译的类名则在右上角的窗口中直接显示反编译后的源代码。
三、 独树一帜的DAVA
DAVA不是一个独立的JAVA反编译器,而是JAVA代码优化工具Soot的一部分。Soot和JODE一样是纯JAVA开发的,也是一个独立的JAR包,但却不能通过双击直接运行,而是象JAD一样在命令行状态运行。
Soot对环境变量的配置要求非常严格,通常情况下要对CLASSPATH做如下设置:
Set CLASSPATH=%CLASSPATH%;c:\sootdir\sootclasses-2.1.0.jar;.;
其中的c:\sootdir\是下载的soot类包放置的路径,CLASSPATH末尾的.;代表了当前目录,如果不加上这个的话Soot经常会报一个找不到类的错误。
DAVA是作为Soot的一个参数使用的,通常的用法如下:
Java soot.Main –f dava –d c:\javasource javatest
注意最后的类名不用带.class后缀,因为它默认是处理class文件,这个操作与前述的JAD的参数效果相同。
DAVA采取了流程优化的方式进行反编译,与传统反编译思路不尽相同,但却对改变流程类的加密方法有独特的反编译效果。
上述的三种工具各有千秋,但效果都非常不错。经测试,它们基本上都可以把JDK自带的一些例程完全反编译,然后不加任何修改可再编译成功,并能正常运行!
F. 将.class文件反编译成.java文件都有哪些工具
反编译工具jad简单用法
以下假设jad.exe在c:\java目录下
一、基本用法
Usage:jad [option(s)]
直接输入类文件名,且支持通配符,如下所示。
c:\java\>jad example1.class
c:\java\>jad *.class
结果是将example1.class反编译为example1.jad。将example1.jad改为example1.java即得源文件。
二、Option -o
不提示,覆盖源文件
三、Option -s
c:\java\>jad -sjava example1.class
反编译结果以.java为扩展名。
四、Option -p
将反编译结果输出到屏幕
c:\java\>jad -p example1.class
将反编译结果重定向到文件
c:\java\>jad -p example1.class>example1.java
五、Option -d
指定反编译的输出文件目录
c:\java\>jad -o -dtest -sjava *.class
G. 如何反编译一个exe文件,并修改里面一句代码
1、首先打开浏览器,网络搜索“反编译工具ILSpy”,选择一个安全的网站进行下载。
H. java反编译器怎么用
目前最好的反编译工具,是小颖JAVA源代码反编译超级引挚,Google一下就有下的,很好用