计算机系统实验四:二进制程序逆向工程

2023-11-03

参考教材:计算机系统基础 第二版 袁春风 机械工业出版社
参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162

计算机系统实验导航

实验一:环境安装 https://blog.csdn.net/weixin_46291251/article/details/122477054

实验二:数据的存储与运算 https://blog.csdn.net/weixin_46291251/article/details/122478255

实验三:程序的机器级表示 https://blog.csdn.net/weixin_46291251/article/details/122478979

实验四:二进制程序逆向工程 https://blog.csdn.net/weixin_46291251/article/details/122479554

实验五:缓冲区溢出攻击 https://blog.csdn.net/weixin_46291251/article/details/122479798

实验六:程序的链接 https://blog.csdn.net/weixin_46291251/article/details/122480049

实验源码: xxx

准备

实验内容:

1 二进制炸弹实验的内容、方法和基本步骤;
2 程序机器级表示、分析与调试基本知识和方法的应用。

实验目标:

1 加深对程序的机器级表示、汇编与反汇编、二进制程序分析与调试、逆向工程等方面知识
的理解和掌握;
2 从程序员角度认识计算机系统,分析高级语言对应的机器行为及其对程序执行结果和性能
的影响,解决计算机系统设计、程序开发过程中的关键问题。
3 掌握各种开源的编译调试工具。

实验任务:

1 学习 MOOC 内容

https://www.icourse163.org/learn/NJU-1449521162
第五周 二进制程序逆向工程
第 1 讲 二进制炸弹实验:概述
第 2 讲 二进制炸弹实验:字符串比较
第 3 讲 二进制炸弹实验:浮点数表示
第 4 讲 二进制炸弹实验:课后实验

2 完成作业

一个二进制炸弹是-个Linux 可执行程序,包含了多个阶段(又称为层次、关卡)。在炸
弹程序运行的每个阶段要求输入一个特定字符串,如果该输入字符串符合程序的要求,该阶段的炸弹就被拆除了,否则炸弹“爆炸_即打印输出 “BOM!!” 的提示。
每个炸弹阶段考察了程序与数据的机器级表示的不同方面,难度逐级递增:
●阶段0:字符串比较
●阶段1 :浮点数表示
●阶段2 :循环
●阶段3 :条件/分支
●阶段4 :递归调用和栈
●阶段5:指针
●阶段6 :链表/指针/结构
●另外还有一个隐藏阶段作为阶段7,只有在阶段4的拆解字符串后附加一特定字符串后,才能在实验最后进入隐藏阶段。

实验的目标是拆除尽可能多的炸弹关卡一分析获得 尽可能多的正确拆解字符串。

运行二进制炸弹可执行程序bomb需要指定0或1个命令行参数(详见bomb.c源文件中
的main0函数):
如果运行时不指定参数,则程序打印出欢迎信息后,期望你按行输入每-阶段用来拆
除炸弹的字符串,程序根据输入字符串决定是通过相应阶段还是引爆炸弹导致该阶
段任务失败。
也可将拆除每一炸弹阶段的字符串按行(- 行-个字符串)记录在一个文本文件(必
需采用Unix/Linux换行格式)中(即实验结果提交文件的形式),然后将该文件作为
运行二进制炸弹程序时的唯- -命令行参数,程序将依次检查对应每一阶段的字符 串
来决定炸弹拆除成败。
注意:如果拆解字符串(来自命令行输入或文本文件)不正确导致相应炸弹阶段被引爆,
程序在输出炸弹爆炸的提示文字“BOM!!” 后,将进入下一阶段的字符串检查(等待命令行
输入或读取文件下一行)而不会终止程序的运行。因此,如果暂时未能正确获得某阶段的拆解字符串,可用任意非空字符串(即不同于空格、制表、换行的一个以上字符)临时作为拆解字符串,从而在引爆相应炸弹阶段后,跳到以后阶段继续开展实验。

phase0:字符串

实验结果记录

首先将实验文件中的bomb文件反汇编得到bomb.s文件
在这里插入图片描述

进入bomb.s找到phase_0函数的入口:
这里利用less打开文件,然后输入/phase_0搜索关键词,然后按N快捷键找到匹配的函数入口位置(这里是第二次出现的位置),这样就找到了phase_0的汇编代码,如下图所示:
在这里插入图片描述

分析phase_0的汇编代码,以了解其执行逻辑:
第一行汇编语句是push %ebp,目的是将ebp寄存器在main函数中的旧值压入栈中保存。
然后第二条汇编指令 mov %esp %ebp,把保存了ebp旧值的存储单元地址作为当前栈帧的起始地址,并保存于栈帧基址寄存器ebp中。执行完后,ebp中就存放了phase_0的栈真的起始地址。以后就可以用ebp的地址加偏移量来定位phase_0的各个成员以及其实参的存放位置。
下面两条sub语句分别从栈顶指针寄存器esp中减去了0x8,它们实际上完成了对栈帧空间的分配和。
接下来的三条语句分别是push、pushl和call语句。
在这里插入图片描述

这三条语句完成了对一个名为strings_not_equal的调用,且这个函数位于0x8049c61这个偏移量上。其中第一个push语句把函数的最后一个参数值为常量0x804a1e0的地址压入栈中,第二个pushl语句把函数的第一个参数(ebp寄存器+0x8地址对应的内容,实际上是传递给phase_0函数的第一个参数的值)压入栈中。
Call函数访问了strings_ not equal函数,分析该函数的汇编代码可知:该函数如果输入的两个字符串参数的内容相同, strings_ not equal函数将返回0。
接下来的test指令测试eax寄存器即strings_ not equal函数的返回值是否为0。
在这里插入图片描述

Test如果成立,则在示例汇编代码中, test指令测试时, 将使得je指令跳转到程序的正常结束位置。反之,如果两个字符串的内容不一致,将调用explode. bomb函数引爆炸弹。
故可知成功解开炸弹的关键是通过test,而test是判断strings_ not equal返回0,strings_ not equal返回0的条件是判断的两个字符串相等,这两个字符串一个是程序读入的钥匙,另一个是位于0x804a1e0的一个内置字符串
在这里插入图片描述

所以可以推断,位于0x804a1e0的字符串就是题目的解。
下面通过gdb调试的方法查看位于0x804a1e0的内置字符串的具体值。

结果分析与讨论

打开gdb调试程序,断点设置在phase_0里面调用strings_not_equal函数的额call指令的位置
在这里插入图片描述

由反汇编文件得知其位于0x8049465的位置,在这个位置设置断点然后开始运行。
运行后程序要求输入字符串,随便输入一个字符串后程序运行到断点的位置。
然后利用x/1s 0x804a1e0查看位于0x804a1e0位置的一个字符串。
输出的结果即为第一个阶段的答案。
在这里插入图片描述

运行程序,输入上述获得的第一个阶段的答案,可见成功解开了炸弹,顺利来到第二个关卡。

在这里插入图片描述

phase1:浮点数表示

实验结果记录
进入bomb.s找到phase_1函数的入口:
这里利用less打开文件,然后输入/phase_1搜索关键词,然后按N快捷键找到匹配的函数入口位置(这里是第二次出现的位置),这样就找到了phase_1的汇编代码,如下图所示:
在这里插入图片描述

其中三个指令为:
在这里插入图片描述

分别表示:
将一个整型数值传送到地址为-0xc(%ebp)的存储单元中
将其中的值加载到浮点寄存器栈顶
从浮点栈顶将值存储到地址为-0x18(%ebp)的存储单元
即可以理解为用一个整型常量0x97684a1对-0x18 (%ebp)中存储的浮点数进行初始化。
在这里插入图片描述

然后程序用一个push指令将一些数据压入栈中并进一步调用sscanf函数,此函数按照格式字符串参数的指示,从其第一个参数所对应的输入字符串中读出数据。

0x8(%ebp)中存储了传入本阶段phase 1主函数的第一个参数,即在本阶段输入的字符串的地址。
此阶段完成从输入字符串中读入本阶段所需要的整型数字对的过程。
在这里插入图片描述

对ssca nf函数返回时存储于eax寄存器中的返回值进行检查。该返回值是sscanf成功读入的数据单元的数量。
当读入的整数数量为两个时,将跳转到后续检查继续执行,否则将调用explode_ bomb引爆炸弹。
当确实读入两个整数时,程序将进一步对两对存储单元进行比较,不相等时也将引爆炸弹。
这个部分按照程序内置的常量对读入的数据进行检查。

结果分析与讨论
首先来查看程序内置的数值为多少:
在这里插入图片描述

将整型值0x97684a1通过浮点栈转为双精度浮点表示,并传送到本阶段函数栈帧中地址为-0x1 8(%ebp)处开始连续存放。

查看sscanf读入的格式字符串:
用gdb查看得到:
在这里插入图片描述

在这里插入图片描述

第二个整数的地址对应第四个函数调用参数,即第一个压栈的参数。-0x20(%ebp)
第一个整数的地址对应第三个函数调用参数,即第二个压栈的参数。-0x1c(%ebp)
在这里插入图片描述

-0x18(%ebp):浮点数
-0x1c(%ebp):第1个输入整数
-0x20(%ebp):第2个输入整数
在这里插入图片描述

下面分析两个输入数值与浮点数进行比较的指令处理逻辑。

前两个指令将存放于-0x18(%ebp)处的浮点数的低四个字节,传送到edx寄存器中。
第三条mov指令将存放于-0x1c(%ebp)处的第1个输入整数,传送到eax寄存器中。
最后比较两个寄存器中的内容,如果不相等则通过jne指令跳转到explode_ bomb函数
引爆炸弹,否则继续下阶段比较。
在这里插入图片描述

前三条指令将存放于-0x14(%ebp)处的浮点数的高四个字节,传送到edx寄存器中。
第四条mov指令将存放于-0x20(%ebp)处的第2个输入整数,传送到eax寄存器中。
比较两个寄存器中的内容,如果相等则通过je指令跳转到函数正常结束,否则调用explode bomb函数引爆炸弹。

基于以上分析可知,输入字符串中的一对整数,分别对于程序中浮点数的高32位和低32位,
前面我们看到该浮点数的值来自整型值0x97684a1,
对应的十进制:158762145
对应的二进制:1001011101101000010010100001
即1.001011101101000010010100001 *2^27
符号s为0,指数e为27,有效数字M为1.001011101101000010010100001
符号域sign = s,值为0,二进制位为0。
指数域exp = E + Bias,值为1050,11bit的二进制位为10000011010
小数域0.frac=M - 1,值为0.001011101101000010010100001
52bit的frac域二进制为001011101101000010010100001 加25个0
因为frac域截取了前52位,所以没有位不被精确表示,得到的是一个准确值
合并符号域sign、指数域exp、小数域frac得到浮点数的二进制位。
0100000110100010111011010000100101000010000000000000000000000000
其对应的双精度浮点数的IEEE 754表示为(十六进制字节序列,从高位到低位) :41a2ed0942000000
低32位(从高位到低位)转为十进制有符号整数:41a2ed09 =1101196553
高32位(从高位到低位)转为十进制有符号整数:42000000 =1107296256
因此,本实验阶段的拆解字节串应为:1101196553 1107296256

附:代码main函数部分

1.#include <stdio.h>
2.#include <stdlib.h>
3.#include "support.h"
4.#include "phases.h"
5.
6./* 
7. * Note to self: Remember to erase this file so my victims will have no
8. * idea what is going on, and so they will all blow up in a
9. * spectaculary fiendish explosion. -- Dr. Evil 
10. */
11.
12.FILE *infile;
13.
14.int main(int argc, char *argv[])
15.{
16.    char *input;
17.
18.    /* Note to self: remember to port this bomb to Windows and put a 
19.     * fantastic GUI on it. */
20.
21.    /* When run with no arguments, the bomb reads its input lines 
22.     * from standard input. */
23.    if (argc == 1) {  
24. infile = stdin;
25.    } 
26.
27.    /* When run with one argument <file>, the bomb reads from <file> 
28.     * until EOF, and then switches to standard input. Thus, as you 
29.     * defuse each phase, you can add its defusing string to <file> and
30.     * avoid having to retype it. */
31.    else if (argc == 2) {
32. if (!(infile = fopen(argv[1], "r"))) {
33.     printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
34.     exit(8);
35. }
36.    }
37.
38.    /* You can't call the bomb with more than 1 command line argument. */
39.    else {
40. printf("Usage: %s [<input_file>]\n", argv[0]);
41. exit(8);
42.    }
43.
44.    /* Do all sorts of secret stuff that makes the bomb harder to defuse. */
45.    initialize_bomb();
46.
47.    printf("Welcome to my fiendish little bomb. You have 7 phases with\n");
48.    printf("which to blow yourself up. Have a nice day!\n");
49.
50.    /* Warm up phase! */
51.    input = read_line();             /* Get input                   */
52.    if( phase_0(input) ) {           /* Run the phase               */
53.        phase_defused();             /* Drat!  They figured it out! */
54.        printf("Well done! You seem to have warmed up!\n");
55. }
56.
57.    /* Hmm...  Six phases must be more secure than one phase! */
58.    input = read_line();             /* Get input                   */
59.    if( phase_1(input) ) {           /* Run the phase               */
60.        phase_defused();             /* Drat!  They figured it out! Let me know how they did it. */
61.        printf("Phase 1 defused. How about the next one?\n");
62. }
63.
64.    /* The second phase is harder.  No one will ever figure out
65.     * how to defuse this... */
66.    input = read_line();
67.    if( phase_2(input) ) {
68.        phase_defused();
69.        printf("That's number 2.  Keep going!\n");
70. }
71.
72.    /* I guess this is too easy so far.  Some more complex code will
73.     * confuse people. */
74.    input = read_line();
75.    if( phase_3(input) ) {
76.        phase_defused();
77.        printf("Halfway there!\n");
78. }
79.
80.    /* Oh yeah?  Well, how good is your math?  Try on this saucy problem! */
81.    input = read_line();
82.    if( phase_4(input) ) {
83.        phase_defused();
84.        printf("So you got that one.  Try this one.\n");
85. }
86.    
87.    /* Round and 'round in memory we go, where we stop, the bomb blows! */
88.    input = read_line();
89.    if( phase_5(input) ) {
90.        phase_defused();
91.        printf("Good work!  On to the next...\n");
92. }
93.
94.    /* This phase will never be used, since no one will get past the
95.     * earlier ones.  But just in case, make this one extra hard. */
96.    input = read_line();
97.    if( phase_6(input) ) {
98.        phase_defused();
99. }
100.
101.    /* Wow, they got it!  But isn't something... missing?  Perhaps
102.     * something they overlooked?  Mua ha ha ha ha! */
103.    
104.    return 0;
105.}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机系统实验四:二进制程序逆向工程 的相关文章

  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • PHP 致命错误:未找到“MongoClient”类

    我有一个使用 Apache 的网站 代码如下 当我尝试访问它时 我在 error log 中收到错误 PHP Fatal Error Class MongoClient not found 以下是可能错误的设置 但我认为没有错误 php i
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复
  • 在 Linux 中禁用历史记录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 要在 Linux 环境中禁用历史记录 我执行了以下命令 export HISTFILESIZE 0 export HISTSIZE 0 u
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 在 Mac OS X 上构建 Linux 内核

    我正在做一个修改Linux内核的项目 我有一台桌面 Linux 机器 在上面构建内核没有问题 不过 我要去旅行 我想在途中工作 我只有一台 MacBook 当我尝试构建 Linux 内核时 它抱怨说elf h was not found 我
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • 无法加载 JavaHL 库。- linux/eclipse

    在尝试安装 Subversion 插件时 当 Eclipse 启动时出现此错误 Failed to load JavaHL Library These are the errors that were encountered no libs
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何使用 xterm.js 创建基于 Web 的终端以 ssh 进入本地网络上的系统

    我偶然发现了这个很棒的图书馆xterm js https xtermjs org 这也是 Visual Studio Code 终端的基础 我有一个非常普遍的问题 我想通过基于网络的终端 不在网络中 可能位于 aws 服务器上 访问本地网络
  • 仅打印“docker-container ls -la”输出中的“Names”列

    发出时docker container ls la命令 输出如下所示 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a67f0c2b1769 busybox tail f dev
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • Linux中的CONFIG_OF是什么?

    我看到它在很多地方被广泛使用 但不明白在什么场景下我需要使用它 What is 配置 OF OF 的全名是什么 打开固件 这是很久以前发明的 当时苹果公司正在生产基于 PowerPC CPU 的笔记本电脑 而 Sun Microsystem
  • 我可以从命令行打印 html 文件(带有图像、css)吗?

    我想从脚本中打印带有图像的样式化 html 页面 谁能建议一个开源解决方案 我使用的是 Linux Ubuntu 8 04 但也对其他操作系统的解决方案感兴趣 你可以给html2ps http user it uu se jan html2
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https

随机推荐

  • Win7安装64位CentOS 6.4双系统详细过程

    本文是在两篇文章整合而成 分别是 Mr Johness的 最清晰细致的教程 一步步教你打造Win7 CentOS双系统 和 cjh326419411的 Win7上安装centos6 4 双系统 前者安装centos过程详细 后者考虑了Cen
  • 一文详解RabbitMQ,RocketMQ和Kafka的异同

  • 【华为OD统一考试B卷

    在线OJ 本题通过率100 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1
  • Android——Intent.addflags的使用

    activity的启动模式 4种 在manifest里面对应的activity中增加android launchMode 属性指定启动模式 和在activity中增加 Intent intent2 new Intent intent2 se
  • react项目axios网络请求封装(包含取消请求不报错)

    搭建项目过程中有一个封装网络请求的步骤 现在已react vite项目详细描述一下 api文件夹 包含path文件夹 请求接口地址 index ts 统一导出接口调用点 server ts api请求通用操作 tool ts 处理serve
  • JMETER分布式压测(精讲教程)

    第一步 关闭防火墙 第二步 在负载机上要安装JMeter 并确保其中一台机器作为主的controller 其它的机器作为agent 注意事项 Jmeter的版本要求一致 Jmeter都能正常的运行 安装JDK1 8并配置JDK环境变量与Jm
  • 网络编程之IO复用机制(多路IO转接)之epoll_create,epoll_ctl,epoll_wait函数06

    1 epoll create函数 epoll create是创建一个epoll句柄 参数size用来告诉内核监听的文件描述符的个数 跟内存大小有关 include
  • 17、java.lang.UnsatisfiedLinkError: No implementation 处理方法

    一 问题现象 在使用第三方生成的 so 库时 遇到下面的bug UnsatisfiedLinkError No implementation found for java lang UnsatisfiedLinkError No imple
  • Python调用,爬虫JS逆向——动态数据,数据加密获取步骤和方法。

    Python调用 爬虫JS逆向 ajax类型数据 JS逆向 加密数据 加密数据是无法通过在后台找到接口进行请求来获取数据 目标网站 https www qimingpian com finosda project pinvestment 1
  • recycleView GridLayoutManager 列 左右贴边,中间居中

    适配 recycleView GridLayoutManager 列 左右贴边 中间居中 mGridView setLayoutManager new GridLayoutManager getActivity 4 int screenWi
  • C语言中fork和vfork创建进程的区别

    fork 和vfork 是在操作系统中用于创建新进程的两个系统调用 它们有以下区别 创建新进程的方式 fork 会创建一个新的子进程 该子进程与父进程几乎完全相同 包括程序代码 数据和进程上下文等 而vfork 则创建一个新的子进程 但与父
  • ElasticSearch基本概念

    1 重要特性 分布式的实时文件存储 每个字段都被索引并可被搜索 实时分析的分布式搜索引擎 可以扩展到上百台服务器 处理PB级结构化或者非结构化数据 2 基本概念 索引 indices Database 数据库 类型 type Table 文
  • 华为HCIA(三)

    链路本地地址接口标识64bit 当STP端口到了Forwarding状态后 会转发流量 也处理报文 在TCP IP模型中 会话层 表示层和应用层 都规划成了应用层 路由表包含目的地址和掩码 优先级 cost 下一跳和出接口 Destinat
  • Python初学者必看学习路线图!!!

    python应该是近几年比较火的语言之一 很多人刚学python不知道该如何学习 尤其是没有编程基础想要从事程序员工作的小白 想必应该都会有此疑惑 包括我刚学python的时候也是通过从网上查找相关资料以及从学校课程学习才确定python学
  • IPD流程中,TR2评审的内容、评审要素和评审标准

    在IPD流程中 TR2评审是项目开发过程中的一个重要里程碑评审 旨在评估项目的技术进展和实施情况 以下是TR2评审的详细内容 评审标准和评审要素的说明 评审内容 1 项目概述 项目背景 介绍项目的起源 目的和重要性 项目目标 阐明项目的具体
  • centos服务器Mongodb下载及相关操作

    要在 CentOS 上安装 MongoDB 请按照以下步骤操作 1 打开终端或 SSH 连接到 CentOS 服务器 2 添加 MongoDB 的 YUM 源 运行以下命令以创建一个名为 mongodb org repo 的新文件 sudo
  • 会些java知识,然后要学习spring boot大概需要多长时间?

    Spring boot要学什么 要学到什么程度 以及相关的学习方法是什么 学习spring boot大概需要多长时间 每个人的学习能力 每天能花费时间来学习的时间也是不确定的 这些很难量化 但极好形容 需要学到能帮你找到一份工作的程度 任何
  • QT谷歌输入法纯widget方式没有qml

    谷歌拼音输入法移植至QT 样式 移植方法 第一种直接带入源码编译 第二种链接方式 修改相关参数 修改输入法界面尺寸大小 使用方式 初始化部分 调用键盘 互动 THE END 最近看了输入法部分的实现方式 也看了不少文章 qml实现 不太了解
  • neo4j+python知识图谱构建(基于豆瓣TOP250电影)

    爬取内容网站 https movie douban com top250 start 0 filter 第一步 明确节点nodes和关系relations 针对本文 有4个节点 4个关系 一个节点就相当于一个实体 注明 因为一部电影可以属于
  • 计算机系统实验四:二进制程序逆向工程

    参考教材 计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课 计算机系统基础 四 编程与调试实践 https www icourse163 org learn NJU 1449521162 计算机系统实验导航 实验一 环境安装 htt