笔记:
masm:是微软为×86微处理器开发的汇编开发环境,在windows下开发汇编的工具,是一个汇编器
pip:pip 是一个现代的,通用的 python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。
笔记:
【Java的Hotspot虚拟机】:HotSpot VM,它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。采用HotSpot的Java虚拟机,已经很难说Java是被虚拟机解释执行了, 原因是HotSpot实际上是把Java的bytecode编译成Native code, 然后运行。
HotSpot VM的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知JIT编译器以方法为单位进行编译。
如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准编译和OSR(栈上替换)编译动作。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更多的代码优化技术,输出质量更高的本地代码。
【JIT】:Just-in-time compilation,即时编译。动态编译的一种形式,是一种提高程序运行效率的方法。通常,程序有两种运行方式:静态编译与动态解释。静态编译的程序在执行前全部被翻译为机器码,而解释执行的则是一句一句边运行边翻译。
即时编译器则混合了这二者,一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。相对于静态编译代码,即时编译的代码可以处理延迟绑定并增强安全性。
Mozilla Firefox使用的JavaScript引擎SpiderMonkey也用到了JIT的技术
· JavaScript引擎:“JavaScript 引擎”通常被称作一种 虚拟机。JavaScript 引擎的基本工作是把开发人员写的 JavaScript 代码转换成高效、优化的代码,这样就可以通过浏览器进行解释甚至嵌入到应用中。事实上,JavaScriptCore 自称为“优化虚拟机”。简单来说它的唯一的目的就是读取和编译 JavaScript 代码。
【Docker】:在pdf中是显示为lightweight virtual machines的分类,从字面意思来说我觉得这是轻量级的vm。Docker 使用 Google 公司推出的 Go 语言 进行开发实现,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
· 比较传统vm和docker的不同:
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程
可以看出,每个虚拟的应用不仅包括几十M的存储和一些比较的二进制文件和库文件,还包括整个重达几十G的操作系统。
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
可以看出,Docker引擎所包括的仅仅是应用及其所支撑它的依赖的组件。它运行在主机系统的用户空间内一个独立的进程,和其他组件共享内核。总之,它具有vm的资源隔离和分配的优势,更高效。
总结来说。这种的vm就是硬件和软件的隔离来确保程序直接跑在处理器上,当然会用一些特别的机制来实现隔离和安全。从而更加的有效率。传统的是虚拟出硬件和软件。来跑程序。这是我认为的最大的区别。
【Hypervisor】
Hypervisor,又称虚拟机器监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的软件、固件或硬件。
被Hypervisor用来执行一个或多个虚拟机器的电脑称为主体机器(host machine),这些虚拟机器则称为客体机器(guest machine)。hypervisor提供虚拟的作业平台来执行客体操作系统(guest operating systems),负责管理其他客体操作系统的执行阶段;这些客体操作系统,共同分享虚拟化后的硬件资源。
304challenge:
【nc】:netcat能通过tcp和udp在网络中读写数据。通过与其他工具结合和重定向,可以在脚本中以多种方式使用它。netcat所做的就是在两台电脑之间建立链接并返回2个数据流
对于具体的netcat 命令实例参考点击打开链接
给的challenge中让我们nc一个ip和一个端口,之前没有接触过nc命令,所以尝试一下,特意装了一个kali, 来和Ubuntu做测试。如下
首先我netstat -luntp了一下Ubuntu的端口,看哪些开放
但是我在用kali 扫描ubuntu的开放端口的时候,发现仅 5355 和22 是开的。(为啥自己扫描的端口和nc出来的open端口是不一致的呢)
(备注笔记:
关于谁能ping通谁的问题(接触网络安全,发现什么都是不安全的,所以在考虑上传有ip的图片时有一定的顾虑,虽然自己觉的vm中的ip无非是虚拟出来的,别人根本ping不通,自己用的ip地址也是局域网内的私有地址,也应该ping不通,所以还是了解了这方面的知识。):
首先:
· 知道ping的原理是非常重要的:在学计算机网络的时候,我们知道ping命令实则发送一个ICMP请求信息给目的地并报告是否受到了ICMP的回声应答,它是用来检查网络是否畅通或者网络连接速度的命令,我们往目标IP地址发送一个数据报,对方就要返回一个同样大小的数据报,以此判断目标主机的存在。
· ping的工作流程
1.在同一网段内:如果主机A 执行了一个"ping 192.168.0.5"的话,ping命令会构建一个ICMP请求数据报,连同这个ip地址交给ip层协议,然后加上一些控制信息,想办法得到目的ip的mac地址,构造数据帧,主机B的ip地址和自己的掩码发现它跟自己同属一个网络,如果在自己的缓存中找到了目的主机的MAC,则说明以前有过通信,没有则发送ARP请求广播,得到b的mac。主机B收到数据帧后,如果是发给自己的就介绍该数据帧,随后构建ICMP应答包发送回去。
2.不在同一网段内:如果主机A运行同样的命令,开始还是想办法得到MAC地址,然后IP通过计算目的主机和自己不在同一网段内,就直接交给路由表处理,由路由表把MAC娶过来。路由得到数据帧后,再跟主机D进行联系,如果找不到,就向主机A返回一个超时的信息。
· ping测试
1.Ping自己本机Ip: 这个肯定ping的通。。
2.主机ping百度: 这个也是ping的通的。
3.主机ping虚拟机:ping的通
4.虚拟机ping主机:ping的通
5.虚拟机ping虚拟机:也可以ping通。(双向都可以)
6.主机和虚拟机ping 自买的服务器:可以ping通。
那么,究竟,外网可不可以ping内网的ip,因为在学校,都是使用校内网,所以没办法验证,但是从网上搜了一下,是不能ping通的,因为我们内网用的都是私有IP,ping的时候只能pingISA外网卡,我们知道,内网的私有地址是不能发布到公网上的,内网和外网使用NAT,除非用连接到公司内部,才能ping通。又想到304challenge描述中说实验室搭建了一个公网(!),这也就能说的通了, 所以 nc 这个ip也是可以的。
题目说可以nc这个ip 端口号方便测试和查看效果,不知道说的是啥意思,所以自己用ubuntu 来nc一下kali 看看到底能干什么事情。
以下关于nc的测试:
我跟随网上教程,并设置成监听1567端口,然后用client来nc 这个ip的1567端口,发现不行,因为总是 deny 操作,随后我发现,需要先开放1567这个端口,使用方法如下:使用第一条命令开启端口,第二条命令查看端口状态,可见是开启。
随后我们在server端监听1567 端口,使用client端 nc 这个ip的 端口, 输入内容,可见在server端是同步显示的,随后处于好奇,我在server端输入内容后,client端并不显示。
随后我关闭双方后,视图再监听,在client再发送内容。发现不能发送
原因在命令前面,我们退出的时候,已经提示 stop了那个端口。可见端口已经关闭了。
稀里糊涂的测试了这些,都是网上的内容,我觉得还是找到一个linux 官方的源文档比较好。还有 nc到底能干什么还没有测试,总不能只能通信一下,究竟怎么用来方便测试和演示结果。
)
其中opcode:指令助记符;cond:执行条件;S:是否影响CPSR寄存器的值;Rd:目标寄存器;Rn:第1个操作数的寄存器;operand2:第2个操作数; 大多数时候可以根据CPSR的条件标志位觉得是否该执行指令。当条件满足时才执行,否则不执行。
其中 arm指令的16码就像之前的汇编所遇到的eq,ne啥的,这里不一一赘述了,总之就是指令的规范
【反汇编要干的事情是什么】一般来说使用编译器、汇编器和链接器中的一个或几个创建可执行程序。为了回溯编程过程(或对程序进行逆向工程),我们使用各种工具来撤销汇编和编译过程。这些工具就叫做反汇编器和编译器。所以说,反汇编器就是撤销汇编过程,因此我们可以得到汇编语言形式的输出结果(以机器语言作为输入)。反编译器则以汇编语言甚至是机器语言为输入,其输出结果为高级语言。那么,貌似注册机类的软件就是对目标软件进行反汇编,从而得到软件注册码验证部分的汇编代码,然后根据此写出逆向算法,再编译生成注册程序。。
2018.4.10
IDA PRO指南学习 (最近要交第一版查重版论文,所以时间集中论文比较多)
2018.4.11
看了一些权威指南,上网找了一些资料,还是不太理解怎么分析指令格式,但是首先还是应该对反汇编出来的东西看懂。
2018.4.12
今天怼了一天的本科论文,晚上看了一些汇编的书,白天中午看了一下challenge.的反汇编代码
2018.4.13
写论文写到傍晚,发现Google 得代理插件崩了,用机房的还是正常,捣鼓了一晚上的Google。安装卸载10多遍,网上的方法都试了,最后发现,有时候感觉重启是万能的。。。。
2018.4.14
学习时间及内容: 304
一直在理解问题中有有欠缺,我用虚拟机myvm运行了一下hello程序,发现hello程序所实现的功能就是用户输入什么,即系统输出什么。所以我们要做的就是分析 myvm,分析出 使用哪些指令和对哪些寄存器的操作来使得hello实现了这样的功能。
接下来我们分析myvm干了什么事情,我们通过反汇编代码和IDA pro提供的伪代码来分析。
接下来,我将一部分一部分的分析:
一开始,在经过简单的push入栈操作和mov操作后,比较edi和2的值,随后我从上下文中搜索edi是什么,是否还出现过此寄存器,发现edi的操作都是跟mov操作有关,猜想edi存的东西应该是作为参数传进来的。随后如果edi不等于2的话,跳c47.
bd0: 41 56 push %r14
bd2: 53 push %rbx
bd3: 50 push %rax
bd4: 48 89 f3 mov %rsi,%rbx //rsi给rbx
bd7: 83 ff 02 cmp $0x2,%edi //比较edi和2的值
bda: 75 6b jne c47 <__cxa_finalize@plt+0x1a7>
在c47处,一开始也是进行了一些mov操作给相应的寄存器,随后eax里的内容自身异或,调用了一个fprintf的函数,而这个函数从字面意思我们判定是从一个file流文件中打印里面的内容,随后jmp c3d,在c3d处就是出栈操作,不罗列代码。随后我们接着继续讨论如果edi==2的话,进行什么操作。
//edi!=2 从bda处跳转过来
c47: 48 8b 05 aa 13 20 00 mov 0x2013aa(%rip),%rax # 201ff8 <__cxa_finalize@plt+0x201558>
c4e: 48 8b 38 mov (%rax),%rdi
c51: 48 8b 13 mov (%rbx),%rdx
c54: 48 8d 35 09 08 00 00 lea 0x809(%rip),%rsi # 1464 <__cxa_finalize@plt+0x9c4>
c5b: 31 c0 xor %eax,%eax
c5d: e8 f6 fd ff ff callq a58
c62: eb d9 jmp c3d <__cxa_finalize@plt+0x19d>
如果edi==2的话,把rip的内容-23的地址给rsi,edi赋值为2,之前已经edi判断为2了,这里为什么还要赋值为2?看到后面的callq函数,我们知道,这是edi又作为一个参数调用signal这个函数,继续往下看,在rbx+8给rdi后,又call了一个函数,在对ce0处的这个函数分析,我们可以知道,这是一个将file open的功能,随后将1给r14所指的地方。nop没有查到,但是通过伪代码知道这应该是个死循环,再往后看,test eax自身,不相等的话跳c24.
在c24处,比较了2和eax的值,不等于2的话,跳c35,调用_cxa_finalize函数。随后结束。
如果eax等于2的话,在c29-c30处我们可以看到调用了一个puts的函数,用于输出。大题过程即是如此。
//edi==2 继续
bdc: 48 8d 35 dd ff ff ff lea -0x23(%rip),%rsi # bc0 <__cxa_finalize@plt+0x120>
be3: bf 02 00 00 00 mov $0x2,%edi
be8: e8 63 fe ff ff callq a50
bed: 48 8b 7b 08 mov 0x8(%rbx),%rdi
bf1: e8 ea 00 00 00 callq ce0 <__cxa_finalize@plt+0x240>
bf6: 48 89 c3 mov %rax,%rbx
bf9: 4c 8d 35 14 14 20 00 lea 0x201414(%rip),%r14 # 202014 <__cxa_finalize@plt+0x201574>
c00: 41 c7 06 01 00 00 00 movl $0x1,(%r14)
c07: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
c0e: 00 00
c10: 48 89 df mov %rbx,%rdi
c13: e8 78 02 00 00 callq e90 <__cxa_finalize@plt+0x3f0>
c18: 85 c0 test %eax,%eax
c1a: 75 08 jne c24 <__cxa_finalize@plt+0x184>
c1c: 41 83 3e 00 cmpl $0x0,(%r14)
c20: 75 ee jne c10 <__cxa_finalize@plt+0x170>
c22: eb 11 jmp c35 <__cxa_finalize@plt+0x195>
c24: 83 f8 02 cmp $0x2,%eax
c27: 75 0c jne c35 <__cxa_finalize@plt+0x195>
c29: 48 8d 3d 50 08 00 00 lea 0x850(%rip),%rdi # 1480 <__cxa_finalize@plt+0x9e0>
c30: e8 e3 fd ff ff callq a18
c35: 48 89 df mov %rbx,%rdi
c38: e8 a3 01 00 00 callq de0 <__cxa_finalize@plt+0x340>
c3d: 31 c0 xor %eax,%eax
c3f: 48 83 c4 08 add $0x8,%rsp
c43: 5b pop %rbx
c44: 41 5e pop %r14
c46: c3 retq
ce0处的代码如下:
ce0: 41 57 push %r15
ce2: 41 56 push %r14
ce4: 53 push %rbx
ce5: 48 8d 35 fc 0a 00 00 lea 0xafc(%rip),%rsi # 17e8 <__cxa_finalize@plt+0xd48>
cec: e8 9f fd ff ff callq a90
cf1: 48 89 c3 mov %rax,%rbx
cf4: 48 85 db test %rbx,%rbx
cf7: 0f 84 cd 00 00 00 je dca <__cxa_finalize@plt+0x32a>
2018.4.15
学习时间及内容:更新内容:昨天没分析完的分析完了添在上面。
随后看了i春秋的一些CTF视频。看了一些里面提到的网站和知识点。
2018.4.16
我一开始以为换个blog很简单,无非是把csdn上的copy过去,怪不得sym说不急,原理github pages需要自己配,然后我就一直看相关的资料。直解从网上找了相关的教程,用的大牛的model,用Atom把里面的东西及config文件改了一下。但是用jekyll 生成不了静态html,好像是权限的问题,正在查资料解决ing~
2018.4.17
今天上午出去了一趟,下午回来在搞二专业论文。
看了一下中央出的那个<我是黑客>,然后对照着那本python的蛇书回顾了一下第一阶段的知识点。随后搞二专业论文
2018.4.19
针对老师的论文审批视频改论文。
2018.4.20
回家
2018.4.21
学习内容及时间 IDA权威指南+栈溢出的原理及基本ROP技术原理
2018.4.22
学习内容。 看汇编的pdf书籍,针对昨天的内容找了一些相关的例子,对函数的帧栈有了一定的认识,然后类比到之前接触的反汇编
2018.4.23
学习内容:
空
2018.4.24
学习内容:看汇编书,晚上回来刷知乎
2018.4.25
学习内容:看汇编
2018.4.26
学习内容: 出去了一趟,改二专业论文。
2018.4.27
空
2018.4.28
学习内容:看汇编
2018.4.29-5.1 空
2018.5.2
学习内容: 本来想把龙书看完,发现有一定的难度,所以回过头来把本科编译原理看一遍,龙书做补充吧。
2018.5.3
学习内容:
2018.5.4
学习内容:304题目
1.
Signal ()函数1. 功能:设置某一信号的对应动作
第一个参数signum:指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号
第二个参数handler:描述了与信号关联的动作,sighandler_t类型的函数指针
2.
sub_CE0()
3.fopen(a1,"rb")
fopen()文件顺利打开后,返回指向该流的文件指针,如果文件打开失败,则返回null
rb意味只读二进制 binary
4.
fseek
int fseek(FILE *stream, long offset, int fromwhere)
重定位流(数据流/文件)上的文件内部位置指针
fseek(v1, 0LL, 2); 以文件尾为基准
函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
5.
函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。
返回值为long型
在这里前两句话的意思就是先把指针放到文件最后,然后调用ftell函数从而得到 文件的长度即为v3。随后一个fseek将指针置于文件首。
2018.5.5
学习内容: 汇编
2018.5.6
空
2018.5.7
学习内容:304
char *__fastcall sub_CE0(const char *a1)
{
FILE *v1; // rax@1
FILE *v2; // rbx@1
__int64 v3; // r15@2
void *v4; // r14@2
char *v5; // rbx@2
v1 = fopen(a1, "rb"); //以只读binary的形式打开名为a1的文件,返回该流的文件指针
v2 = v1;
if ( v1 )//如果打开成功
{
fseek(v1, 0LL, 2);//stream指向最后
v3 = ftell(v2); //返回文件位置指针当前位置相对文件首的偏移字节数。在此即文件大小
fseek(v2, 0LL, 0); //stream指向开头
v4 = malloc(0x10000uLL); //malloc动态分配内存,返回void未确定类型指针。unsigned long long
memset(v4, 0, 0x10000uLL); //为新申请的内存做初始化工作
fread(v4, 1uLL, v3, v2); //从文件中将数据一个个的独到malloc的内存中
fclose(v2); //关闭数据流
_mm_storeu_si128(
(__m128i *)&unk_202018 + 4096,
_mm_unpacklo_epi64((__m128i)(unsigned __int64)&unk_202018, (__m128i)((unsigned __int64)&unk_202018 + 0x8000)));
memcpy(&unk_202018, v4, 0x10000uLL); //把v4所指向的全部内容放到&unk_202018
_mm_storeu_si128((__m128i *)&unk_202018 + 4097, 0LL);
*(_QWORD *)((char *)&unk_202018 + 65566) = 0LL;
*((_WORD *)&unk_202018 + 32785) = 32764;
*((_QWORD *)&unk_202018 + 8197) = 0LL;
v5 = (char *)&unk_202018 + 0x10000;
free(v4);
}
else //文件打开失败
{
v5 = 0LL;
}
return v5;
}
笔记:
void *memset(void *s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。注意:p不要求必须是一个16-bit对齐的一个变量的地址;
备注:对于在关闭数据流之后的系列的对内存的操作没有搞懂是干什么。但是对于CE0这个函数的作用应该就是将我们虚拟机所要执行的文件读入进来进行分析,应该相当于词法分析,随后回到main函数,再跑E90,而E90这个函数,应该就是对于相应指令对应的操作。
2018.5.9
学习内容:304
虽然觉得里面是对指令的操作。一开始我以为里面应该有包含指令的结构体,但是找了很长时间没有找到定义。所以应该没有结构体。对于虚拟机的具体实现还是不了解。重点应该就是虚拟机是如何读指令的。以及switch的到底是什么。
2018.5.10
空:近期准备答辩。有则更新