Reverse CTF Writeup
|
|
|
- 易 能
- 7 years ago
- Views:
Transcription
1
2 目录 见龙在田 - 注册... 1 飞龙在天 -login.htm... 3 龙跃在渊 - IgniteMe.exe... 7 潜龙勿用 -greek_to_me.exe 神龙摆尾 -notepad.exe 密云不雨 -pewpewboat.exe 突如其来 -payload.dll 双龙取水 -zsud.exe 震惊百里 -flair.apk 时乘六龙 -remorse.ino.hex 龙战于野 -shell.php 履霜冰至 -covfefe.exe 亢龙有悔 - 一次 APT 攻击分析 -[missing] Layer 0: 抛砖引玉 ( 攻击场景介绍 ) Layer 1: 金蝉脱壳 ( 下载程序 ) Layer 2: 无中生有 ( 程序框架 ) Layer 3: 树上开花 ( 插件分析 ) Layer 4: 顺手牵羊 ( 信息窃取 ) Layer 5: 声东击西 ( 内网渗透 ) Layer 6: 暗度陈仓 ( 偷取重要文件 ) Layer 7: 反客为主 ( 还原 lab10.zip.cry) Layer 8: 釜底抽薪 (get flag!!!)... 91
3 见龙在田 - 注册 9 月 2 日凌晨,Flare-on 开通了第四届的逆向挑战赛, 网址为
4 国内的很多用户在填写完信息提交的时候发现页面有如下提示 : 什么鬼, 难道注册就是第一关吗? 其实, 注册页面使用了 google 的人机身份验证, 所以注册需要使用 VPN 才可以注册成功 通过 VPN 访问的页面如下 :
5 飞龙在天 -login.htm 序 : 注册成功后就看到了第一关, 显示要下载名为 login.html 的文件,
6 通过文件名可以知道通过的此部分就正式开启逆向之路了, 在浏览器 中打开此文件, 显示如下 : 随便输入一段字符串, 提示如下 : 看来得看源代码了 <html> <head> <title>flare On 2017</title> </head> <body> <input type="text" name="flag" id="flag" value="enter the flag" /> <input type="button" id="prompt" value="click to check the flag" /> <script type="text/javascript"> document.getelementbyid("prompt").onclick = function () { var flag = document.getelementbyid("flag").value; var rotflag = flag.replace(/[a-za-z]/g, function(c){return String.fromCharCode((c <= "Z"? 90 : 122) >= (c = c.charcodeat(0) + 13)? c : c - 26);}); if ("[email protected]" == rotflag) { alert("correct flag!"); } else { alert("incorrect flag, rot again"); } } </script> </body> </html> 红色部分为关键的加密代码, 经过分析, 发现关键代码为 ROT13 的算法, 这个算法为一个对称算法, 加密后的字符串再次加密就会还原明文
7 ROT13: 只对字母进行编码, 用当前字母往前数的第 13 个字母替换当前字母, 例如当前为 A, 编码后变成 N, 当前为 B, 编码后变成 O, 以此类推顺序循环 那现在有两种方式可以获得 flag: Method 1. 一种是将比较的参考字符串填入到输入框中, 利用 WEB 调试器, 让代码运行到和参考比较的地方, 查看比较的字符串, 便会发现 flag Method 2. 另一种是编写代码实现 ROT13 的算法如下 : ''' File:rot13.py Auth:SkyPlant CreateTime: :30 CopyRight:@nsfocus ''' import sys def rot13(instr): outstr = ""; for ch in instr: if ch.isalpha(): if chr(ord(ch)+13).isalpha(): outstr += chr(ord(ch)+13) else: outstr += chr(ord(ch)-13) else:
8 return outstr outstr += ch if name == ' main ': instr = sys.argv[1] outstr = rot13(instr) print outstr 运行结果如下 : $ python rot13.py [email protected] [email protected]
9 龙跃在渊 - IgniteMe.exe 序 : 拿到程序后, 首先在命令行上运行一下, 看有什么提示
10 F:\>IgniteMe.exe G1v3 m3 t3h fl4g: aaaaaaaaaaaa N0t t00 h0t R we? 7ry 4ga1nz plzzz! F:\> 根据提示可以知道如果输入了正确的 flag, 那么程序应该会有不同的提示 将程序载入到 IDA, 看一下验证流程 void noreturn start() { DWORD NumberOfBytesWritten; // [sp+0h] [bp-4h]@1 } NumberOfBytesWritten = 0; hfile = GetStdHandle(0xFFFFFFF6); dword_ = GetStdHandle(0xFFFFFFF5); WriteFile(dword_403074, ag1v3m3t3hfl4g, 0x13u, &NumberOfBytesWritten, 0); sub_4010f0(numberofbyteswritten); if ( sub_401050() ) // Key : Must Be 1 WriteFile(dword_403074, ag00dj0b, 0xAu, &NumberOfBytesWritten, 0); else WriteFile(dword_403074, an0tt00h0trwe_7, 0x24u, &NumberOfBytesWritten, 0); ExitProcess(0); 函数 sub_ 的返回值来决定在终端显示成功还是失败 signed int sub_401050() { int len; // ST04_4@1 int i; // [sp+4h] [bp-8h]@1 unsigned int j; // [sp+4h] [bp-8h]@4 char v4; // [sp+bh] [bp-1h]@1 len = strlen(inputbuf); v4 = sub_401000(); // return 0x04 for ( i = len - 1; i >= 0; --i ) { outbuf_403180[i] = v4 ^ inputbuf[i]; // xor V4 v4 = inputbuf[i]; // Set V4 Value } for ( j = 0; j < 0x27; ++j ) { if ( outbuf_403180[j]!= (unsigned int8)refbuf_403000[j] )// Must Equal
11 } } return 0; return 1; // return from here 验证的算法为从输入的末尾开始读取每一个字节与 V4( 初始值位 0x04) 进行异或, 将结果传送给指定的数组, 并将输入的当前位置字节赋值给 V4 参与比较的结果如下 : 编写解密代码如下 : #Solution for flare-on challage 2 #Create By SkyPlant #Create Time : 2017/09/02 13:51 key = "\x0d\x26\x49\x45\x2a\x17\x78\x44\x2b\x6c\x5d\x5e\x45\x12\x2f\x17\x2b\x44\x6f\x6e\x56\x09\x5 F\x45\x47\x73\x26\x0A\x0D\x13\x17\x48\x42\x01\x40\x4D\x0C\x02\x69" flag = "" ch = 0x4 for i in range(0,0x27): ch = ord(key[0x26-i]) ^ ch flag = flag + chr(ch) flag = flag[::-1] print flag 运行后结果如下 : $ python solution2.py [email protected]
12 潜龙勿用 -greek_to_me.exe 序 :
13 闯入第三关之后, 会看到 FLARE 给了你一些赞赏, 但同时对你的能力还有一点的怀疑, 他们是这么说的 我的天! 怀疑我的能力? 不能忍! 下载下来, 就是干! 双击运行, 眼前一片漆黑, 既无法输入数据, 又没法获得数据 使用 IDA 打开, 静态看一下到底是怎么回事, 通过查看 IDA, 只有四个函数, 从 start 函数往里面跟进, 函数 sub_ 创建套接字, 监听 2222 端口, 接收数据, 并从接收到的数据中取出一个字节, 与 loc_40107c 处的数据进行异或操作, 操作完之后, 将异或后的 loc_40107c 传入 sub_4011e6 进行校验, 整体流程图为 :
14 经过分析流程图, 解决的思路就比较简单了 - 暴力破解 通过动态调试, 将 loc_40107c 处的数据取出来, 长度为 0x79 可以定义一个 for 循环, 从 0x0 开始, 每次加 1, 与我们取出来的 loc_40107c 数据进行程序中的操作, 然后带入 sub_4011e6, 并判断返回值是否为 0xFB5E, 如果是的话, 就说明找到的 key 参考代码如下 :
15 #include "stdafx.h" #include<windows.h> #include<iostream> using namespace std; WORD sub_4011e6(byte *a1_code, unsigned int a2_size); void xorfunc(byte index); int main(int argc, char* argv[]) { for (byte index = 0x0; index <= 0x10000; index++) { xorfunc(index); } return 0; } void xorfunc(byte index) { byte TargetCode[] = { 0x33,0xE1,0xC4,0x99,0x11,0x06,0x81,0x16, 0xF0,0x32,0x9F,0xC4,0x91,0x17,0x06,0x81, 0x14,0xF0,0x06,0x81,0x15,0xF1,0xC4,0x91, 0x1A,0x06,0x81,0x1B,0xE2,0x06,0x81,0x18, 0xF2,0x06,0x81,0x19,0xF1,0x06,0x81,0x1E, 0xF0,0xC4,0x99,0x1F,0xC4,0x91,0x1C,0x06, 0x81,0x1D,0xE6,0x06,0x81,0x62,0xEF,0x06, 0x81,0x63,0xF2,0x06,0x81,0x60,0xE3,0xC4, 0x99,0x61,0x06,0x81,0x66,0xBC,0x06,0x81, 0x67,0xE6,0x06,0x81,0x64,0xE8,0x06,0x81, 0x65,0x9D,0x06,0x81,0x6A,0xF2,0xC4,0x99, 0x6B,0x06,0x81,0x68,0xA9,0x06,0x81,0x69, 0xEF,0x06,0x81,0x6E,0xEE,0x06,0x81,0x6F, 0xAE,0x06,0x81,0x6C,0xE3,0x06,0x81,0x6D, 0xEF,0x06,0x81,0x72,0xE9,0x06,0x81,0x73,0x7C }; int i = 0; do { (TargetCode[i]) = (index^(targetcode[i])) + 0x22; i++; } while (i < 0x79); if (sub_4011e6(targetcode, 0x79) == 0xFB5E) { printf("%x",index); getchar(); } } WORD sub_4011e6(byte *a1_code, unsigned int a2_size)
16 { } int v2_size; // edx@1 WORD v3; // cx@1 BYTE *v4_code; // ebx@2 WORD v5; // di@3 int v6; // esi@3 WORD v8; // [sp+0h] [bp-4h]@1 v2_size = a2_size; v3 = 0xff; v8 = 0xff; if (a2_size) { v4_code = a1_code; do { v5 = v8; v6 = v2_size; if (v2_size > 0x14) v6 = 0x14; v2_size -= v6; do { v5 += *v4_code; v3 += v5; ++v4_code; --v6; } while (v6); v8 = (v5 >> 8) + (unsigned int8)v5; v3 = (v3 >> 8) + (unsigned int8)v3; } while (v2_size); } return ((v8 >> 8) + (unsigned int8)(v8&0xff)) ((v3 << 8) + (v3 & 0xFF00)); 经过运行此程序, 可以得到答案是 a2, 接着使用 OD 进行调试 ( 在 程序等待连接时, 可以写个脚本进行连接, 并发送数据 ), 将参与异 或操作的那个字节修改为 a2
17 if 语句条件成立, 继续使用 OD 往下跟踪, 发现程序往一块内存中 不断的放入数据, 在数据窗口中定位到目标地址, 可以看到程序正在 将 flag 放到那块内存中
18 神龙摆尾 -notepad.exe 序 : 题目提示我们是否在 VM 中运行, 意思就是暗示我们需要在虚拟 机中运行 ( 在本机运行了, 果然没有反应 ) 运行之后, 首先弹出了
19 一个时间的对话框, 然后就显示 notepad 界面 如果直接定位到弹出对话框的地址处进行分析, 完全看不出来是什么意思, 因为程序调用的函数都是经过动态获得的, 所以还是使用 IDA 从头开始看 从 IDA 中可以看到, 此程序有 99 个函数, 不过不要被这个数字吓到, 跟着程序流程走, 还是比较简单的 调用 sub_1013f30 时, 传入的第二个参数是 C:\Users\username\flareon2016challenge, 如果没有这个文件夹的话, 就需要创建此文件夹, 因为后期程序将遍历此文件夹中的文件 在 FindFirstFile 循环遍历中, 只有一个函数 sub_1014e20, 此函数的第二个参数是遍历到的文件的全路径, 无疑, 我们需要跟进这个函数, 查看这个函数对遍历到的文件所做的操作 这个函数有很多 if else 分支, 不过它调用的函数, 经过注释之后, 流程还相对简单, 此函数将遍历到的文件映射进内存中, 并判断此文件是否为 EXE 文件, 由此可知, 程序要查找的文件是 EXE 形式的 PE 文件
20 继续往下看代码, 程序还会判断当前运行的平台的文件属性, 如果平台不正确, 则不执行操作 ( 难怪我在本机运行没有效果 ) 通过最开始定位 MessageBox 代码的位置, 可以得知它是在 sub_10146c0 里面调用的 这个函数也是重点函数, 需要重点分析 后面的代码只是一些文件的内存对齐操作, 先不用理会 在 sub_10146c0 中, 有几个 if 判断语句, 是用来比较时间戳的 : 图中的 v62_ntheader 是当前运行程序的 NT 头,a2_NtHeader 是遍历到的文件的 NT 头,NtHeader+8 得到的数据是 TimeDateStamp, 如果符合 if 条件, 则会将时间格式进行转换并会弹出对话框, 显示时间, 程序会显示的时间整理如下 : 2016/09/08 18:49:06 UTC 2016/09/09 12:54:16 UTC
21 2008/11/10 09:40:34 UTC 2016/08/01 00:00:00 UTC 在调用函数 sub_10145b0 时, 传入的第三个参数是 key.bin 文件的绝对路径, 所以我们还需要在 flareon2016challenge 文件夹下创建名为 key.bin 的文件 这个函数的作用是将遍历到的文件的特定偏移处的数据写入 key.bin 文件中, 写入的大小是 8 字节 将 if 语句走完之后, 后面又会读取 key.bin 中的数据, 经过函数 sub_ 运算后, 调用 MessageBox 弹出结果 从读取的数据长度可知, 前面的 if 语句都需要进入, 也就说明了 flareon2016challenge 文件夹下要有 4 个 EXE 并且这四个 EXE 的时间戳要对应上 从文件夹的名称 flareon2016challenge 和遍历此文件夹中的应用程序可以猜测到, 这些应用程序有可能就是 2016 年的 flareon 的题目 所以就将 2016 年的题目下载下来, 找到时间戳正确的 EXE 放到 flareon2016challenge 文件夹下 现在有两种解题思路 : 第一种 : 修改时间戳
22 多次运行 notepad.exe, 修改程序的时间戳, 让它进入到不同的 if 语句中, 按照 if 语句的顺序进行修改即可, 原始的时间戳为 0x , 后期需要修改四次, 依次为 0x57D1B2A2,0x57D2B0F8, 0x ,0x579E9100, 运行后将弹出 flag 第二种 : 写脚本进行破解通过对比时间戳, 我们可以知道程序要找的四个文件分别是哪几个, 我们也知道了程序要读取的文件的位置, 分别为 0x400,0x410, 0x420,0x430 只有函数 sub_ 对这些数据进行了操作 所以我们可以将对应文件对应位置处的数据读取出来, 编写程序对这些数据进行运算, 同样可以得到答案 参考脚本 : memdata = "\x37\xe7\xd8\xbe\x7a\x53\x30\x25\xbb\x38\x57\x26\x97\x26\x6f\x50\xf4\x75\x67\xbf\xb0\xef\xa 5\x7A\x65\xAE\xAB\x66\x73\xA0\xA3\xA1" key1_from_2016ch_1 = "\x55\x8b\xec\x8b\x4d\x0c\x56\x57" key2_from_2016ch_2 = "\x8b\x55\x08\x52\xff\x15\x30\x20"
23 key3_from_2016ch_6 = "\xc0\x40\x50\xff\xd6\x83\xc4\x08" key4_from_2016ch_4 = "\x00\x83\xc4\x08\x5d\xc3\xcc\xcc" flag = "" key = key1_from_2016ch_1 + key2_from_2016ch_2 + key3_from_2016ch_6 + key4_from_2016ch_4 len = len(key) print len for i in range(0,len): flag = flag + chr(ord(memdata[i]) ^ ord(key[i])) print flag 结果如下 :
24 密云不雨 -pewpewboat.exe 序 : 穿过弯弯曲曲的盘山路, 来到了河边, 旁边有块牌子提示, 请放
25 松一下, 来做个游戏, 只有通关了, 才会有通往彼岸的吊桥 使用 file 命令查看文档格式, 发现是一个 64 位的 ELF 程序 $ file pewpewboat pewpewboat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux , BuildID[sha1]=580d3cee c9e7b0ae44d65d57deb52912, stripped 运行后界面如下 : A _ _ _ _ _ _ _ _ B _ _ _ _ _ _ _ _ C _ _ _ _ _ _ _ _ D _ _ _ _ _ _ _ _ E _ _ _ _ _ _ _ _ F _ _ _ _ _ _ _ _ G _ _ _ _ _ _ _ _ H _ _ _ _ _ _ _ _ Rank: Seaman Recruit Welcome to pewpewboat! We just loaded a pew pew map, start shootin'! Enter a coordinate: 这是一个射击游戏, 通过猜测目标位置来进行射击, 成功打到所有目标即可过关 如此以来, 需要逆向看看靶子上目标的坐标是如何生成的了 先来看看他的限制条件 : 1. 尝试的次数 当射击达到一定次数以后, 提示弹药使用完毕 2. 相互关联 无法通过修改内存直接得到坐标, 必须通过计算完成 3. 输入限制 只能输入一个坐标, 多个坐标同时输入会产生
26 错误的结果 注意到以上条件, 则需要看的是如何生成坐标的了 首先要确定, 坐标生成所需要内容是什么, 下图中展示的靶和目标坐标生成的代码段 for ( i = 0; i <= 99; ++i ) { memcpy(dest, (char *)&unk_6050e * i, 0x240uLL);// GetMapData sub_40304f(dest, 576LL, v8); // DecryptMap if ( (unsigned int)sub_403c05(( int64)dest)!= 1 )// game break; v8 = *((_QWORD *)dest + 2); } 每次会取 0x240 字节长度的内存进行解析, 我们简单看下这个内存区的结构, 从内存开始处解析如下 : 输入的坐标信息会保存到 X Y 这两项中, 经过如下运算 : 计算结果保存到 location_input 项中去 接着就是进行比较 : 如果对比成功, 就会显示出 nice shot 的提示, 当然完成所有关卡 之后, 会对 calc_sum 项进行校验, 如果答案正确, 那么就显示最后 的提示语 :Thanks for playing!
27 根据逆向的结果, 编写脚本, 直接获取所有坐标 : #trans hex_string to int def trans_value(v): ans = 0 length = len(v) for i in range(0,length): ans = ans + (ord(v[i])<<(8*i)) return ans def mapcor(v): value = trans_value(v) offset = -1 mcor = "" vcor = [] vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) vcor.append([0,0,0,0,0,0,0,0]) #print hex(value) while(value): offset = offset + 1 if(value % 2): vcor[offset>>3][offset%8] = 1 mcor = mcor + chr((offset>>3)+ord('a')) + chr((offset%8)+ord('1')) + " " value = value >> 1 for i in range(0,8): line = "" for j in range(0,8): if (vcor[i][j] == 1): line = line + "*" else: line = line + " " print line return mcor
28 map = [ ] "\x00\x78\x08\x08\x78\x08\x08\x00", "\x00\x88\x88\x88\xf8\x88\x88\x00", "\x7e\x81\x01\x01\xf1\x81\x81\x7e", "\x00\x00\x00\x90\x90\x90\x90\xf0", "\x00\xf8\x40\x20\x10\xf8\x00\x00", "\x07\x09\x07\x05\x09\x00\x00\x00", "\x00\x00\x00\x70\x10\x70\x10\x70", "\x00\x3e\x08\x08\x08\x09\x06\x00", "\x00\x00\x00\x44\x44\x44\x28\x10", "\x00\x00\x00\x0c\x12\x12\x12\x0c", "\x00\x00\x00\x00\x00\x00\x00\x00" cnt = len(map) for i in range(0,cnt): val = mapcor(map[i]) print "map[%d]:%s" %(i,val) 通关后, 拿到最后的提示字符, 去除中间无效字符 PEW, 得到最后的提示语句, 告诉我们需要重新排序获取的字符 排序后的字符是 :OHGJURERVFGUREHZ, 经过 ROT13 解密后, 得到 BUTWHEREISTHERUM, 字符长度是 17 字节 将 17 字节的结果作为如下红色字符函数的输入参数运行 if ( fgets(&s, 17, stdin) ) { v2 = (char)(s & 0xDF) - 65;
29 } v3 = v5-49; if ( v2 < 0 v2 > 7 v3 < 0 v3 > 7 ) { sub_403411(( int64)&s); } else { *(_QWORD *)(a1 + 8) = 1LL << (8 * (unsigned int8)v2 + v3); *(_BYTE *)(a1 + 28) = s & 0xDF; *(_BYTE *)(a1 + 29) = v5; } 得到的结果如下 :
30 突如其来 -payload.dll 序 : 从给出的名字可以知道出题者想考察一下参与者对于 Windows
31 动态库的掌握情况 查看导出表如下 : 这里有个提示, 需要根据格式进行调用 手动输入如下命令 >rundll32 payload.dll,entrypoint EntryPoint 提示如下 : 猜测可能在程序运行的过程中修改了导出函数名, 通过, #1 的方法调用 1 号导出函数, 命令如下 : >rundll32 payload.dll,#1 发现提示发生了变化
32 此时 dump 出内存中的 payload.dll 数据, 再次查看导出表, 如下 所示 : 1 号导出函数名和地址都被修改, 分析这个新的 1 导出函数 发现了用于弹出消息框的代码, 使用 x64dbg, 修改命令行为 C:\Windows\System32\rundll32.exe payload.dll,#1, 调试该 dll, 下断 点修改跳转, 使其执行 else 分支, 结果如下所示 :
33 分析 else 分支的代码可以得知, 函数会从带解密函数表中解密出 一段代码然后执行, 带解密函数表如下所示 : 可以分析出该函数表为 26 个待解密函数地址和一个用于解密函数的函数地址, 我们在前面获得的 key[24]=0x6f 即为, 解密出的函数表中下标为 24 的函数执行后弹出的消息框, 以此类推, 只要我们解密出所有其他的函数, 就可以得到完整的 flag
34 首先我们尝试通过修改解密函数时的偏移来修改要解密的函数地址, 结果发现出现无法运行, 即解密的 key 不是通过的, 每个函数解密时应该有自己的 key, 追踪这个 key 是怎么得到的, 动态调试发现 key 的值为修改后的导出函数名, 那么就要找导出函数是在哪里被修改的, 经过调试发现, 当调用 LoadLibrary 函数加载完 payload.dll 时, 函数名就已经被修改, 因此对 DllEntryPoint 函数进行调试, 发现了如下代码 : 通过 c++ 在初始化全局对象的时候, 调用执行 _CRT_INIT --> _initterm(unk_ , unk_ ) ; 该函数会遍历 unk_ 和 unk_ 之间的地址, 发现有值则执行该地址的函数 我们发现在此之间有一个函数的地址 : 分析该函数会找到如下代码 :
35 该处是一个解密代码, 下断点动态调试, 发现这块会解密出导出 函数名, 并且要解密的数据地址由下标决定, 往回找该下标在哪获取 的 : 可以看到 v5 是函数 sub_ 的返回值, 直接下断点动态调试, 观察返回值为 0x18, 正好的之前得到的 key[24]=0x6f 下标, 直接将其修改为 0, 观察到解密出了不同的函数名, 继续执行, 注意在下面位置处 patch 程序 继续执行, 将弹出以下对话框 :
36 所以这次找到了正确的修改处, 一次将其修改为 即 可得出 Flag:
37 双龙取水 -zsud.exe 序 : 到达第七关, 依然是一个游戏关, 下载后打开程序, 界面如下图
38 所示 : 一个传统的文字解密类游戏, 是不是勾起了很多老程序员的回忆 敲击 help 查看所有命令, 可以看到游戏定义了一些内容 : 1 行走方向:North South East West Up Down; 2 动作 :get drop wear remove look inv( 检查背包 ) say put Take [something] off 从游戏中, 我们能直接获取到的目前是只有这么多信息, 我们分析下他的程序, 看看如何能获取到 key: 用 IDA 查看代码, 发现里面有个深调用, 隐藏了真实的函数实现 :
39 耐心跟下去, 第一个函数的目的是创建一个线程, 我们分析一下线程函数准备做什么 第一个深调用目的是获取 HTTP 系列相关的函数地址, 获取之后会直接调用, 在当前计算机中添加一个临时 HTTP 页面, 监听本地发来的 HTTP 请求 : 着重看下函数 sub_4010e1, 主要功能是接收数据并进行解析 : 将收到的内容根据 & 符号分割, 并且解析 k= 和 e= 后的内容, 处 理的 k= 后的内容时, 会将 k= 后的部分输入到以下算法中 :
40 之后和 e= 后的内容进行 hash 运算 : 得到结果后回复给客户端, 如果计算后 flag 标志为 0, 那么会给 客户端回复页面 : 至此, 第一个函数分析完毕 回到第二个函数, 第二个函数也是深调用, 里面内嵌了另外一个 深调用函数, 解到最后一层, 可以看到程序加载了
41 CorBindToRuntimeEx 函数 这个函数的功能是为非托管代码增加调用托管代码的功能, 也就是说一个正常的 C++ 程序, 可以通过这个函数加载相应的.Net 执行库, 来运行.Net 类的程序 接着程序向内存中加载了一个 DLL, 这个 DLL 是在本程序的数据段中存放的,dump 下来以后, 可以看到是一个 powershell 脚本 最后程序 Hook 了 rand 函数和 srand 函数 :
42 至此,EXE 已经分析完毕 接下来我们看一下 dump 出来的 Powershell 脚本文件 Powershell 脚本比较大, 但是注释写的非常清楚, 直奔主题, 我们直接查看控制人物移动的代码 从上至下看, 第一个框中有 key 字样, 可能我需要在地图中找一 个 key? 第二个框中调用了 rand() 函数, 我们知道 rand 这个函数已经
43 被 Hook 了,rand 函数的功能是什么? 第三个框中, 似乎 key 字符存在, 就会将当前人物移动到初始房间? 第四个框提示如果我们走的方向满足某种条件就会触发 key 的特效 带着这四个问题, 我们开始重新审视这个游戏, 首先我需要找到 key, 在脚本搜索一下 key 字段 : 可以通过提示字符看到 key 藏在桌子的抽屉里面 接下来, 当我们获取了 key, 输入一个方向, 就会和 rand 出来的字符进行对比, 如果相同的话, 就会对 key 进行一次运算, 似乎会得出什么内容, 那么 rand 是怎么实现的? 回到 rand 函数的实现部分 : 我们发现他有一个数组, 里面存放了 35 个字符, 这是不是对应的 方向的编号?
44 回到脚本中, 搜索一下找到 enum, 如此就可以与上面的表格内容 对应了 那么如何输入这些方向呢, 玩游戏可以发现, 房间的通向都是固定的, 也没有 up 和 down 方向, 仔细查看发现有个能够输入所有方向的工作间, 移动到工作间, 并且保证不会出现任何 key warm 的提示 接着顺次输入方向表中的所有字符, 得到最后的答案 : You can start to make out some words but you need to follow the RIGHT_PATH!@66696e646b e6d616e d0a 后面这串字符是 ASCII 字符, 翻译过来就是 f i n d k e v i n m a n d i a, 寻找 kevin 在迷宫中进行寻找, 可以找到 kevin, 跟 kevin 说话, 他仅仅说 hello, 并没有任何提示, 难道是方向错了么? 重新回到脚本中, 找到 say 控制函数, 分析一下 :
45 注意第一个框, 在这个房间中需要有 key 这个物品,key 在我们身上, 所以需要 drop 下来, 接着看第二个框, 我们身上需要带着 helmet, helmet 在进房间的时候在房间中放着, 我们需要 get 它, 接着 wear 它, 最后再和 kevin 对话,kevin 会告诉我们 key: 得到 key: '6D E 67 5F F C C D 6F 6E 2E 63 6F 6D'. 附 : 如果并未发现 rand 函数被替换, 那么就需要对正确答案进行爆破求
46 解, 编写如下 ps1 脚本 :(encoded 就是我们直接复制原本的 key, 由 于过长, 这里就不完全显示了 ) $baseurl = ' $encoded = 'BANKbEPxukZfP2EikF8jN04iqGJY0RjM3p++Rci2RiUFvS9RbjWYzbbJ3BSerzwGc9EZkKTvv1JbHOD6ldmehDxyJGa 60UJXsKQwr9bU3WsyNkNsVd/XtN9/6kesgmswA5Hvroc2NGYa91gCVvlaYg4U8RiyigMCKj598yfTMc1/koEDpZUhl9D y4zhxuufhbiyrxfariynsiqjaeynb0r93nsaqpnognrqg23oyd3rpp4thd8g6vkjuxltrgxv7px2cwdohuxkbvq6edum FSKpnNB7jAKo..EAwkG/jtoZzPtEVBhQ==' $array='n','s','e','w','d','u' $keytext='' $text='' $flag=0 $prekey='' for($i=0;$i -le 32; $i++) { for ($j=0;$j -le 5;$j++) { $prekey=$keytext $keytext+=$array[$j] $uri = "${baseurl}?k=${keytext}&e=${encoded}" $r = Invoke-WebRequest -UseBasicParsing "$uri" $decoded = $r.content if ($decoded.tolower() -NotContains "whale") { $split = $decoded.split() $text += $split[0..($split.length-2)] $text += ' ' $encoded = $split[-1] $flag=1 break } else { $keytext=$prekey } } if ( $flag -eq 0 ) { echo "ERROR!!!" break
47 } else { $flag = 0 } if (!#decoded) { echo "END!" echo "$text" } } echo "$keytext" echo "$text" 但是, 经过爆破, 你只能获取到以下提示字符 : You can start to make out some words but you need to follow the? 返回的 key 是 : ZipRg2+UxcDPJ8TiemKk7Z9bUOfPf7VOOalFAepISztHQNEpU4kza+I MPAh84PlNxwYEQ1IODlkrwNXbGXcx/Q== 接下来, 你只能去调试 powershell 脚本, 接着就会发现 rand 函数的问题
48 震惊百里 -flair.apk 序 : 这是一道 Android APK 逆向题, 总共 4 关, 每一关输入正确的 password 后才能进入下一关
49 以下是反编译后程序结构 : 第一关 :
50 使用 apktool 解包 apk 程序, 并在解压后的目录下搜索 who run it 字符串, 最后发现在 activity_michael.xml 文件中, 因此, 第 一关需要分析反编译后的 michael 文件
51 分析以上算法, 可以得到以下结论 : (1) Password 总长度为 12; (2) Pw[0] = M (3) Pw[1] = Y (4) Pw[2-4] = PRS (5) Pw[5] = H
52 (6) Pw[6] = E (7) Pw[7] == pw[8], 并且两者连接后计算 hashcode 得到的值为 3040 (8) Pw[9-10] = FT (9) Pw[11] = W 以上算法中, 唯一需要计算的是 pw[7] 和 pw[8] 的值, 由于 password 为可见字符, 因此在 0x20 到 0x7e 之间爆破, 获取到第 7 位和第 8 位的值 : 计算结果为下划线 _, 即 pw[7]=pw[8]= _. 因此, 第一关的 password 为 :MYPRSHE FTW 第二关 :
53 通过同样的方式搜索字符串 SOMETHING TO NIBBLE ON, 最后发现第二关为 Brian 从第二关开始, 代码做了混淆, 静态分析时可根据需要重命名函数名 静态分析 Brian 代码, 可以看到, 使用函数 teraljdknh 判断输入的值与函数 asdjfnhaxshcvhuw 的返回值是否相同, 相同时 password 验证通过 :
54 使用 Android Studio + Smalidea 动态调试, 在 teraljdknh 函数 处下断点, 参数 v 为输入的值, 参数 m 为正确的 password 最终获取到第二关的 password 为 :hashtag_covfefe_fajitas!
55 第三关 : 第三关中需要点亮 4 颗星, 才能继续下一步 搜索字符串 CARRY ON MY WAYWARD SON, 了解到第三关为 Milton 分析 Milton 校验算法, 输入值经过 Stapler.neapucx() 函数运算后, 与 nbsadf() 函数返回值做比较, 两者相同, 则验证通过
56 分析 Stapler.neapucx() 函数, 可以看到该函数功能为将十六进 制字符串转换为字节数组 : 使用 Android Studio 动态调试, 在函数 nbsadf 返回值处下断点, 最终获取到该函数返回值为字节数组 : {16, -82, -91, -108, -125, 30, 11, 66, -71, 86, -59, 120,
57 -17, -102, 109, 68, -18, 57, -109, -115}; 将该字节数组转换为十六进制字符串, 即为该题 password 最终结果为 :10aea594831e0b42b956c578ef9a6d44ee39938d
58 第四关 : 第四关为 Printer, 校验算法与第三关一样, 输入的 password 经 过 Stapler.neapucx() 转换为字节数组后, 与 Stapler.poserw 返回
59 值做比较, 两者相同, 验证通过 : 使用 Android Studio 动态调试, 在 Stapler.poserw 返回值处下断点, 获取到返回值为字节数组 : {95, 27, -29, -55, -80, -127, -60, 13, -33, -60, -96, 35, -127, 86, 0, -114, -25, 30, 36, -92}
60 使用第三关的程序, 将字节数组转换为十六进制字符串, 即为第 四关 password:5f1be3c9b081c40ddfc4a ee71e24a4 四关全部通过后, 获取到该题 flag:
61 时乘六龙 -remorse.ino.hex 序 :
62 该题目是一道 Arduino 平台逆向题, 题目提供了一个 Arduino 二 进制程序, 打开后, 看到内容如下 : 木有开发板? 不知道有啥好用的 Arduino 调试器? 这些都不重要, IDA 在手, 跟我走! 使用 IDA 打开程序, 注意选择处理器类型为 Atmel AVR [AVR] : 没错,IDA 反汇编后, 不需要动态调试, 纯静态分析, 获取 flag,
63 以下便是获取 flag 的代码 : ROM:0545 loc_545: ; CODE XREF: sub_536+11j ROM:0545 st X+, r1 ROM:0546 cpse r25, r26 ROM:0547 rjmp loc_545 ROM:0548 ldi r25, 0xB5 ; ' ROM:0549 std Y+1, r25 ROM:054A std Y+2, r25 ROM:054B ldi r25, 0x86 ; ' ROM:054C std Y+3, r25 ROM:054D ldi r25, 0xB4 ; ' ROM:054E std Y+4, r25 ROM:054F ldi r25, 0xF4 ; ' ROM:0550 std Y+5, r25 ROM:0551 ldi r25, 0xB3 ; ' ROM:0552 std Y+6, r25 ROM:0553 ldi r25, 0xF1 ; ' ROM:0554 std Y+7, r25 ROM:0555 ldi r18, 0xB0 ; ' ROM:0556 std Y+8, r18 ROM:0557 std Y+9, r18 ROM:0558 std Y+0xA, r25 ROM:0559 ldi r25, 0xED ; ' ROM:055A std Y+0xB, r25 ROM:055B ldi r25, 0x80 ; ' ' ROM:055C std Y+0xC, r25 ROM:055D ldi r25, 0xBB ; ' ROM:055E std Y+0xD, r25 ROM:055F ldi r25, 0x8F ; ' ROM:0560 std Y+0xE, r25 ROM:0561 ldi r25, 0xBF ; ' ROM:0562 std Y+0xF, r25 ROM:0563 ldi r25, 0x8D ; ' ROM:0564 std Y+0x10, r25 ROM:0565 ldi r25, 0xC6 ; ' ROM:0566 std Y+0x11, r25 ROM:0567 ldi r25, 0x85 ; ' ROM:0568 std Y+0x12, r25 ROM:0569 ldi r25, 0x87 ; ' ROM:056A std Y+0x13, r25 ROM:056B ldi r25, 0xC0 ; ' ROM:056C std Y+0x14, r25 ROM:056D ldi r25, 0x94 ; '
64 ROM:056E std Y+0x15, r25 ROM:056F ldi r25, 0x81 ; ' ROM:0570 std Y+0x16, r25 ROM:0571 ldi r25, 0x8C ; ' ROM:0572 std Y+0x17, r25 ROM:0573 ldi r26, 0x6C ; 'l' ROM:0574 ldi r27, 5 ROM:0575 ldi r18, 0 ;r18 为索引, 从 0 开始, 依次加 1 ROM:0576 ROM:0576 loc_576: ; CODE XREF: sub_536+46j ROM:0576 ld r25, Z+ ROM:0577 eor r25, r24 ;r25 与 r24 异或 ROM:0578 add r25, r18 ;r25 加上索引 r18 ROM:0579 st X+, r25 ROM:057A subi r18, -1 ; 索引 r18 加 1 ROM:057B cpi r18, 0x17 ROM:057C brne loc_576 ROM:057D lds r24, 0x576 ROM:057F cpi r24, 0x40 ; '@' ROM:0580 brne loc_595 ROM:0581 ldi r22, 0x2B ; '+' ROM:0582 ldi r23, 5 ROM:0583 ldi r24, 0x8F ; ' ROM:0584 ldi r25, 5 ROM:0585 call sub_332 分析上述代码逻辑 : (1) 向 r25 寄存器放了一堆数据 : B5 B5 86 B4 F4 B3 F1 B0 B0 F1 ED 80 BB 8F BF 8D C C C (2) 设置索引从 0 开始, 依次遍历 r25 中的数, 将每个值与 r24 做异或操作, 然后再加上索引的值 r18; (3) 索引加 1, 取 r25 中下一个数, 重复 (2) 中算法 那么这个 r24 的值到底是多少呢? 管他呢, 爆破大法好, 对 r24 从 0x00 到 0xff 取值, 打印出所有计算后的结果 :
65 Python 爆破代码如下 : 最后在所有输出结果中去找 flag: 附 AVR 汇编指令参考地址 : struction_list.html
66 龙战于野 -shell.php 序 :
67 这一题是一个 PHP 文件, 这个 PHP 程序接受 POST 的参数值, 主要通过 MD5 算法计算出一个长度可变的字符串 key, 用 key 字符串通过 XOR 算法解开前面一部分的字符串, 再将这一部分作为字符串去异或求出下一个分组的字符串, 分组长度和 key 长度相同 第一层密文解密 : 这题的 key 其实是很长的, 通过类似弱口令的方式并不能爆破出 POST 的参数值 不过因为算法是一个简单的分组异或, 而且知道加密前是一个合法的 PHP 代码, 可以通过加密后的密文反向推出明文 因为 key 长度是可变的, 准确来说是在 33 到 64 之间, 为了接下来的分析, 最好先求出 key 的长度 因为该算法是分组的, 所以直接拿分组的第一个元素去求解, 得出的值再去求解下一个分组的第一个元素, 以此类推 得出所有分组的第一个元素肯定是在 php 代码中合法的字符, 通过加入该约束条件即可求出 key 长度, 相关代码如下 : ''' calckeylen.py ''' import binascii import base64 import hexdump with open('in.txt','rb') as fd: str=base64.b64decode(fd.read())
68 outstr='' keyli=' abcdef' # 所有可能的字符集合 keylen=31 def checkok(str): # 约束函数 for i in str: if ord(i)<0x20 and ord(i)!=0xa and ord(i)!=0xd: return False return True for keylen in range(33,65):#key 长度变化范围 for key in keyli: tkey=key for i in range(0,len(str)/keylen): res=chr((ord(tkey)^ord(str[keylen*i]))&0xff) outstr+=res tkey=res if checkok(outstr): print "keylen=%d"%keylen outstr='' 结果为 keylen=64 用相同的思路, 可以用字符 0-f 爆破前 64 字节的密文, 通过一小段的分批爆破, 手工查看是否是合法的 php 代码, 从而求出 key 字符串的值 ''' Keysol.py ''' import binascii import base64 import hexdump with open('in.txt','rb') as fd: str=base64.b64decode(fd.read()) outstr='' keyli=' abcdef' key_dic={} g_str='' end=0 def checkok(str): # 约束函数 for i in str: if ord(i)<0x20 and ord(i)!=0xa and ord(i)!=0xd: return False return True
69 def decrypt(key): # 解密函数 global str ret='' for i in range(0,len(key)): ret+=chr((ord(str[i])^ord(key[i]))&0xff) return ret def crack(i): # 递归遍历输出可能的情况 global key_dic global g_str global end if i>=end: print hexdump.hexdump(decrypt(g_str)) return for c in key_dic[i]: g_str+=c crack(i+1) g_str=g_str[:-1] for k in range(0,64): for key in keyli: tkey=key for i in range(0,len(str)/(64)): res=chr((ord(tkey)^ord(str[64*i+k]))&0xff) outstr+=res tkey=res if checkok(outstr): if k not in key_dic.keys(): # 生成所有可能的情况 key_dic[k]=[] key_dic[k].append(key) outstr='' #print key_dic pre_key='d' # 预先设置的 key, 基于前面的猜测 for i in range(0,len(pre_key)): key_dic[i]=[pre_key[i]] end=len(pre_key)+3 #3 个一组去猜, 不要设置过大, 否则无法手动识别 crack(0) #print hexdump.hexdump(str) 值 通过手工识别正确的解密后的字符串, 并不断修改脚本中 pre_key
70 最后得出 : Key=db6952b84a49b934acb436418ad9d93d237df05769afc796d067 bccb379f2cac 第二层密文解密 : 解密出的代码如下 : 根据代码中的网址提示, 通过 google 即可查到提示代码 : site: Raytraced Checkboard
71 1,2,3 解出来的功能应该和提示的代码很类似, 对应关系如下 : Raytraced Checkboard: p01 256b Starfield: Wolfensteiny: 所以解密出来应该是 html+js 之类的代码, 可以通过爆破第一层的方法进行爆破 老方法, 先求正则之后的 key2 长度 : ''' Calckey2len.py ''' import binascii import base64 import hexdump with open('in.txt','rb') as fd: str=base64.b64decode(fd.read()) outstr='' keyli=' abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz@_.-' key_dic={} def checkok(str): for i in str: # 约束函数
72 if ord(i)<0x20 and ord(i)!=0xa and ord(i)!=0xd: return False return True for lk in range(10,20): for k in range(0,lk): for key in keyli: tkey=key for i in range(0,len(str)/(lk+1)): res=chr((ord(tkey)^ord(str[(lk+1)*i+k]))&0xff) outstr+=res if checkok(outstr): if k not in key_dic.keys(): # 生成所有可能的情况 key_dic[k]=[] key_dic[k].append(key) outstr='' #print len(key_dic) if len(key_dic)==lk: print "keylen=%d"%(lk+1) key_dic={} 结果为 keylen=13 得出长度后继续用类似的方法去爆破内容 : 接下来可以得出 flag 正则之后的三部分 : Flag_part1=t_rsaat_4froc Flag_part2=hx ayowkleno
73
74 履霜冰至 -covfefe.exe 序 : 这一题是虚拟机代码分析的题目, 通过 IDA 简单的分析可以知道,
75 此代码写得非常简练, 用一个减法操作和一个条件跳转来模拟左移, 右移, 乘法之类的运算 同时由于虚拟机代码固定长度为 3 个 DWORD, 可以比较方便对虚拟机代码进行解析 定位关键比较处为了略去繁琐的虚拟机代码分析, 快速定位到关键比较地方, 可以通过简单的 hook judge_jmp() 函数, 来对所有执行过的代码进行分析或者日志输出 同时对 vmeip 向上跳的地方进行重点标记, 因为循环一般模拟非常重要的运算 class opcode{ public: DWORD vmeip; // 虚拟机的 eip DWORD op1; // 指令的第一个操作数 DWORD op2; // 指令的第二个操作数 DWORD addr; // 虚拟机的第三个操作数 DWORD op1_val; //op1 指向地址的值 DWORD op2_val; //op2 指向地址的值 }; vector<opcode> g_opcode;
76 map<dword, opcode>g_oplist; void write_log(vector<opcode>&data){ ofstream outfile, fout; char buf[100]; outfile.open("opcode.txt"); for (int i = 0; i < data.size(); i++){ if (i > 1){ if (data[i].vmeip < data[i - 1].vmeip){ sprintf(buf, "%s","re: "); // 可能是循环, 重点标记 } else{ sprintf(buf, "%s", "go: "); } } sprintf(buf + 4, "%d:%08x %08x %08x %08x========>[%08x] - [%08x] = [%08x]\n", i, data[i].vmeip, data[i].op1, data[i].op2, data[i].addr, data[i].op2_val, data[i].op1_val, data[i].op2_val - data[i].op1_val); outfile << buf << endl; } outfile.close(); } 通过分析日志文件, 最后一个循环跳出来的地方和最后开始输出的地方一定是存在关键比较的, 通过改变输入的值则可以发现关键对比的地方, 如下图日志所示, 当改变多次输入的时候, 在 vimeip=0x00000def :[00035e8a] - [0002d7ff] = [ b] 的地方发现只有第一个操作数指向的值 0x2d7ff 是改变的, 而第二个操作数指向的值 0x35e8a 是不变的, 也就是说它是正确的值 在改变输入的过程中还发现, 当输入一个字符, 对比的 vmeip 只执行一次, 输入 2 个字符时候还是一次, 而且要对比的值也改变, 输入 3 个字符时对比地方将会执行 2 次, 输入 4 个字符还是 2 次, 也就是说该程序将两个字符为一组进行运算并求得的值和正确的值对比 当输入非常长的字符串, 对比次数固定在 16, 也就是输入的字符串长度应该是
77 16*2=32 获取对比值因为他是一组组对比的, 搜索空间较小, 可以通过暴力破解的方式来得出正确的字符串 为了暴力破解, 首先得获取所有正确的对比值 : bool my_vm_exec(dword base,dword op1, DWORD op2, DWORD addr){ opcode op; static int g_cnt=0; DWORD eip = 0x12ff6c; op.op1 = op1; op.op2 = op2;
78 } op.addr = addr; op.op1_val = *(DWORD*)(base + op1*4); op.op2_val = *(DWORD*)(base + op2 * 4); DWORD _ebp; _asm{ mov _ebp, ebp } op.vmeip = *(DWORD*)(_ebp+0x1c); if (op.vmeip == 0xdef){ # 执行到关键对比 vmeip 处则输出正确对比值 printf("0x%08x,", *(DWORD*)(base + op2 * 4)); return _vm_exec(base,op1, op2, addr); 暴力破解获取到所有正确的值后, 通过 hook vm_loop 函数, 来对主函数进行不断循环执行尝试正确的字符组合 每循环一次, 通过 hook scanf 喂入尝试的字符组合 同时为了保证虚拟机状态都是最初的状态, 每次循环之前通过 memcpy 将虚拟机的空间 ( 数据和代码 ) 重置, 相关代码如下 : char g_buf[2]; DWORD key_arr[] = { 0x00035e8a, 0x0002df13, 0x0002f58e, 0x0002c89e, 0x b, 0x0002c88d, 0x0002f59b, 0x00036d9c, 0x , 0x000340a0, 0x0002d79b, 0x0002c89e, 0x0002df0c, 0x00036d8d, 0x0002ee0a, 0x000331ff }; // 模拟 scanf 的行为 int my_scanf(char*f, char*in){ static int g_call_scanf = 0; if (g_call_scanf == 0){ *in = g_buf[0]; } if (g_call_scanf == 1){ *in = g_buf[1]; }
79 if (g_call_scanf == 2){ *in = 0xa; } if ((++g_call_scanf) >= 3)g_call_scanf = 0; return 1; } // 不做任何操作 int my_printf(char*f,...){ return 1; } //hook 关键对比地方 bool my_vm_exec(dword base,dword op1, DWORD op2, DWORD addr){ opcode op; static int g_cnt=0; DWORD eip = 0x12ff6c; op.op1 = op1; op.op2 = op2; op.addr = addr; op.op1_val = *(DWORD*)(base + op1*4); op.op2_val = *(DWORD*)(base + op2 * 4); DWORD _ebp; _asm{ mov _ebp, ebp } op.vmeip = *(DWORD*)(_ebp+0x1c); if (op.vmeip == 0xdef){ // 关键对比地方 for (int k = 0; k < 16; k++){ if (op.op1_val == key_arr[k]){ // 破解成功则输出 _printf("%d: ", k + 1); _printf("%c", g_buf[0]); _printf("%c", g_buf[1]); _printf("\n"); } } } return _vm_exec(base,op1, op2, addr); } // 在此函数中进行字符组合尝试 int my_vmloop(dword base, DWORD end, DWORD start){ for (int i = 0; i < 0xff; i++){ for (int j = 0; j < 0xff; j++){ memcpy((void*)0x403000, init_opcode, 0x5000);
80 g_buf[0] = i; g_buf[1] = j; _vmloop((dword)base,end,start); } } return 1; } //hook 主要的函数 extern "C" declspec(dllexport) void hook(){ //dump 下虚拟机最初状态, 用于保证每次虚拟机运行都是最初状态 ifstream infile; ifstream in("opcode.bin", ios::in ios::binary ios::ate); int size = in.tellg(); in.seekg(0, ios::beg); init_opcode = new char[size]; in.read(init_opcode, size); in.close(); DWORD base = (DWORD)GetModuleHandle(NULL); base += 0x1000; MH_Initialize(); MH_CreateHook((void*)base, &my_vm_exec, reinterpret_cast<void**>(&_vm_exec)); MH_EnableHook((void*)base); HMODULE scanf_addr = GetModuleHandle("msvcrt.dll"); base=(dword)getprocaddress(scanf_addr, "scanf"); MH_CreateHook((void*)base, &my_scanf, reinterpret_cast<void**>(&_scanf)); MH_EnableHook((void*)base); HMODULE printf_addr = GetModuleHandle("msvcrt.dll"); base = (DWORD)GetProcAddress(printf_addr, "printf"); MH_CreateHook((void*)base, &my_printf, reinterpret_cast<void**>(&_printf)); base = 0x ; MH_CreateHook((void*)base, &my_vmloop, reinterpret_cast<void**>(&_vmloop)); MH_EnableHook((void*)base); } 运行结果如下 :
81 通过找出对应位置的字符串进行组合, 输入之后得到正确的
82 亢龙有悔 - 一次 APT 攻击分析 -[missing] 实战没有章法, 需要审时度势, 综合运用所掌握内容, 夺取最终 目标 Layer 0: 抛砖引玉 ( 攻击场景介绍 ) 这里描述了一个 APT 攻击场景, 需要通过分析数据包及 PE 文件, 还原整个攻击过程, 获取最终的 flag;
83 Layer 1: 金蝉脱壳 ( 下载程序 ) 分析 coolprogram.exe 其功能为 downloader 程序, 使用 Delphi 语言编译生成的 PE 文件, 其代码相当比较简单, 从指定网址下载一 个加密文件, 并解密执行 ; 其解密算法相当比较简单, 下载文件的头 4 个字节为解密 key, 其后的数据为加密文件内容 ; 下图为解密代码 :
84 根据上面代码编写解密程序获取到 secondstage.exe Layer 2: 无中生有 ( 程序框架 ) 分析 secondstage.exe, 其为后门程序的 main 框架, 其它恶意功能均通过下载 plugin 加载执行 ; 其主要代码包含一个正向连接型后门和一个主动上线的反向连接型后门 ;( 后者在被控主机没有公网 IP 地址, 或者通过 NAT 方式上网等情况下使用 )
85 下图为程序 main 框架的功能类别, 以及各个功能对应的功能号 ; 通过代码分析可以知道 main 框架主要是从网络中获取 plugin, 并安装加载到 main 框架中, 之后通过框架代码解析 c&c 通信数据包, 根据 key 标识调用各个插件执行恶意功能 ; 因此每个插件都有唯一对应的 key 标识 (16 bytes), 用于识别调用对象 ;
86 Layer 3: 树上开花 ( 插件分析 ) 对代码进行分析后确认其使用 c&c 通信的数据包格式为 : key 用于标识调用的 plugin 模块 ; 而其提供的 pcap 数据包中包括大量 c&c 通信内容, 这里分别提取其网络通信过程中, 使用的插件 ; 插件相当比较多, 这里就不一一列举插件分析过程 ; 下图为各个插件对应名称 算法 对应功能 :CRPT 解密插件 8 个,
87 COMP 解压插件 3 个,CMD 功能插件 4 个, 上传文件 3 个 ; Layer 4: 顺手牵羊 ( 信息窃取 ) 通过重放数据包, 可以知道, 黑客入侵到 之后, 获取本机信息, 并且调用 CMD 插件 (m.dll) 功能获取了当前主机屏幕截图, 由于获取到的数据是没有头的 bmp 数据, 这里根据 bmp 的特性只需要知道图片的 width 参数, 之后通过调整 height, 可以查看到屏幕截图的信息, 通过暴力破解 bmp 的 width 可以获取到截屏内容
88 为 ; 其中包含一个 zip 文件的压缩密码 : infectedinfectedinfectedinfectedinfected919; 除此之外还收集到本地一些关于 lab10 的信息, 查看了 Challenge_10 目录下 TODO.txt 文件 ; Layer 5: 声东击西 ( 内网渗透 ) 通过调用 CMD 插件 (s.dll) 功能执行 ping larryjohnson-pc 命令获取该主机的 IP 地址 ( ), 之后利用 CMD 插件 ( f.dll ) 功能下载 pse.exe 和 srv2.exe ( psexec.exe ) 到 主机上, 并利用 psexec 在内网中横向移动到了
89 主机上, 并运行 srv2.exe, 监听本地端口 端 口 (srv2.exe 和 secondstage 功能相同, 一个是正向后门, 一个是反 向后门程序 ); 下一步下载了一个网络代理插件 (p.dll), 安装到 上, 通过这台代理服务器连接 主机上运行的后门程 序 ;
90 Layer 6: 暗度陈仓 ( 偷取重要文件 ) 这里简单理一下思路 ( 针对关键操作进行梳理 ), 1. 黑客入侵到 后, 先获取了屏幕截图 ( 内容包含了一个密码 ); 2. 查看 c:\work\flareon2017\challenge_10\todo.txt, 发现 larry 相关提示 ( 根据前期信息收集结果, 可以知道 larry.johnson 主机名 ); 3. 通过 ping 命令获取到内网 larry.johnson 主机 IP 地址 ( ); 4. 使用 psexec 在 larry.johnson 的主机上安装后门 srv2.exe( 监听本地 端口 ); 5. 之后通过内网代理连接该后门, 通过代理插件上传加密模块到了 larry.johnson 的主机上 c:\staging\cf.exe; 6. 利用加密程序 (cf.exe) 对 lab10 的文件进行加密, 之后将原始文件删除, 并且通过代理传到了黑客手里 ; 下面是 cf.exe 程序代码, 使用 AES 算法对数据进行了加密, 并将文件的 sha256, 路径信息, 文件大小, 加密使用的 iv 保存到文件头部, 并且在文件头部添加 cryp 标识加密文件 ;
91 由于已经分析清楚程序的执行流程, 这里直接解密输出流中, 定 位关键到上传数据包, 对其进行解密后内容为 :( 其中标记的部分为 传输 lab10.zip.cry 文件的数据流 )
92 Layer 7: 反客为主 ( 还原 lab10.zip.cry) 对发送的数据流进行组包后, 获取到 lab10.zip.cry 文件 ;
93 根据 cf.exe 编写解密程序, 对数据包进行解密后获取到 lab10.zip 文件 ; Layer 8: 釜底抽薪 (get flag!!!) 利用之前获取到的 zip 文件密码解压 lab10.zip 文件, 获取到 challenge10;
94 直接运行该程序 get flag:( see you next year :D)
FY.DOC
高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主
C/C++语言 - C/C++数据
C/C++ C/C++ Table of contents 1. 2. 3. 4. char 5. 1 C = 5 (F 32). 9 F C 2 1 // fal2cel. c: Convert Fah temperature to Cel temperature 2 # include < stdio.h> 3 int main ( void ) 4 { 5 float fah, cel ;
+00DE _01EN.book
TCS-NET MODBUS TCS-NET Modbus TCB-IFMB640TLE 1...... 2 2 RS 485... 3 3... 3 4... 4 5... 4 6... 5 7... 6 8... 16 TCS-NET Modbus 1 http://www.modbus-ida.org/ >=3.5 8 8 N*8 ( N = 252.) 16 >= 3.5 Modbus-Master
C语言的应用.PDF
AVR C 9 1 AVR C IAR C, *.HEX, C,,! C, > 9.1 AVR C MCU,, AVR?! IAR AVR / IAR 32 ALU 1KBytes - 8MBytes (SPM ) 16 MBytes C C *var1, *var2; *var1++ = *--var2; AVR C 9 2 LD R16,-X ST Z+,R16 Auto (local
CC213
: (Ken-Yi Lee), E-mail: [email protected] 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,
Guava学习之Resources
Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于
1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->
目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController
Microsoft Word - PHP7Ch01.docx
PHP 01 1-6 PHP PHP HTML HTML PHP CSSJavaScript PHP PHP 1-6-1 PHP HTML PHP HTML 1. Notepad++ \ch01\hello.php 01: 02: 03: 04: 05: PHP 06:
1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File
51 C 51 51 C C C C C C * 2003-3-30 [email protected] C C C C KEIL uvision2 MCS51 PLM C VC++ 51 KEIL51 KEIL51 KEIL51 KEIL 2K DEMO C KEIL KEIL51 P 1 1 1 1-1 - 1 Project New Project 1 2 Windows 1 3 N C test
C 1
C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=
第3章.doc
3 3 3 3.1 3 IT Trend C++ Java SAP Advantech ERPCRM C++ C++ Synopsys C++ NEC C C++PHP C++Java C++Java VIA C++ 3COM C++ SPSS C++ Sybase C++LinuxUNIX Motorola C++ IBM C++Java Oracle Java HP C++ C++ Yahoo
NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p
NOWOER.OM /++ 程师能 评估. 单项选择题 1. 下 描述正确的是 int *p1 = new int[10]; int *p2 = new int[10](); p1 和 p2 申请的空间 的值都是随机值 p1 和 p2 申请的空间 的值都已经初始化 p1 申请的空间 的值是随机值,p2 申请的空间 的值已经初始化 p1 申请的空间 的值已经初始化,p2 申请的空间 的值是随机值 2.
untitled
MODBUS 1 MODBUS...1 1...4 1.1...4 1.2...4 1.3...4 1.4... 2...5 2.1...5 2.2...5 3...6 3.1 OPENSERIAL...6 3.2 CLOSESERIAL...8 3.3 RDMULTIBIT...8 3.4 RDMULTIWORD...9 3.5 WRTONEBIT...11 3.6 WRTONEWORD...12
C/C++ 语言 - 循环
C/C++ Table of contents 7. 1. 2. while 3. 4. 5. for 6. 8. (do while) 9. 10. (nested loop) 11. 12. 13. 1 // summing.c: # include int main ( void ) { long num ; long sum = 0L; int status ; printf
, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1
21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414
新版 明解C++入門編
511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,
BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2
PowerBuilder 9 PowerBuilder Native Interface(PBNI) PowerBuilder 9 PowerBuilder C++ Java PowerBuilder 9 PBNI PowerBuilder Java C++ PowerBuilder NVO / PowerBuilder C/C++ PowerBuilder 9.0 PowerBuilder Native
Chapter #
第三章 TCP/IP 协议栈 本章目标 通过本章的学习, 您应该掌握以下内容 : 掌握 TCP/IP 分层模型 掌握 IP 协议原理 理解 OSI 和 TCP/IP 模型的区别和联系 TCP/IP 介绍 主机 主机 Internet TCP/IP 早期的协议族 全球范围 TCP/IP 协议栈 7 6 5 4 3 应用层表示层会话层传输层网络层 应用层 主机到主机层 Internet 层 2 1 数据链路层
51 C 51 isp 10 C PCB C C C C KEIL
http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom
Ioncube Php Encoder 8 3 Crack 4. llamaba octobre traslado General Search colony
Ioncube Php Encoder 8 3 Crack 4 ->>->>->> DOWNLOAD 1 / 5 2 / 5 Press..the..General..Tools..category4Encrypt..and..protect..files..with..PHP..encoding,..encryption,..ob fuscation..and..licensing... 2016
四川省普通高等学校
四 川 省 普 通 高 等 学 校 计 算 机 应 用 知 识 和 能 力 等 级 考 试 考 试 大 纲 (2013 年 试 行 版 ) 四 川 省 教 育 厅 计 算 机 等 级 考 试 中 心 2013 年 1 月 目 录 一 级 考 试 大 纲 1 二 级 考 试 大 纲 6 程 序 设 计 公 共 基 础 知 识 6 BASIC 语 言 程 序 设 计 (Visual Basic) 9
nooog
C : : : , C C,,, C, C,, C ( ), ( ) C,,, ;,, ; C,,, ;, ;, ;, ;,,,, ;,,, ; : 1 9, 2 3, 4, 5, 6 10 11, 7 8, 12 13,,,,, 2008 1 1 (1 ) 1.1 (1 ) 1.1.1 ( ) 1.1.2 ( ) 1.1.3 ( ) 1.1.4 ( ) 1.1.5 ( ) 1.2 ( ) 1.2.1
Microsoft Word - 01.DOC
第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的
目录
ALTERA_CPLD... 3 11SY_03091... 3 12SY_03091...4....5 21 5 22...8 23..10 24..12 25..13..17 3 1EPM7128SLC.......17 3 2EPM7032SLC.......18 33HT46R47......19..20 41..20 42. 43..26..27 5151DEMO I/O...27 52A/D89C51...28
无类继承.key
无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo [email protected] https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255
untitled
1 DBF (READDBF.C)... 1 2 (filetest.c)...2 3 (mousetes.c)...3 4 (painttes.c)...5 5 (dirtest.c)...9 6 (list.c)...9 1 dbf (readdbf.c) /* dbf */ #include int rf,k,reclen,addr,*p1; long brec,erec,i,j,recnum,*p2;
2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d
2013 18 ( ) 1. C pa.c, pb.c, 2. C++ pa.cpp, pb.cpp, Compilation Error cin scanf Time Limit Exceeded 1: A 5 B 5 C 5 D 5 E 5 F 5 1 2013 C 1 # include 2 int main ( void ) 3 { 4 int cases, a, b,
untitled
8086/8088 CIP /. 2004.8 ISBN 7-03-014239-X.... TP313 CIP 2004 086019 16 100717 http://www.sciencep.com * 2004 8 2004 8 1 5 500 787 1092 1/16 16 1/2 391 000 1 2 ii 1 2 CAI CAI 3 To the teacher To the student
概述
OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3
( CIP) /. :, ( ) ISBN TP CIP ( 2005) : : : : * : : 174 ( A ) : : ( 023) : ( 023)
( CIP) /. :, 2005. 2 ( ) ISBN 7-5624-3339-9.......... TP311. 1 CIP ( 2005) 011794 : : : : * : : 174 ( A ) :400030 : ( 023) 65102378 65105781 : ( 023) 65103686 65105565 : http: / /www. cqup. com. cn : fxk@cqup.
SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基
开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些
Microsoft PowerPoint - string_kruse [兼容模式]
Strings Strings in C not encapsulated Every C-string has type char *. Hence, a C-string references an address in memory, the first of a contiguous set of bytes that store the characters making up the string.
新・明解C言語入門編『索引』
!... 75!=... 48 "... 234 " "... 9, 84, 240 #define... 118, 213 #include... 148 %... 23 %... 23, 24 %%... 23 %d... 4 %f... 29 %ld... 177 %lf... 31 %lu... 177 %o... 196 %p... 262 %s... 242, 244 %u... 177
VB程序设计教程
高 等 学 校 教 材 Visual Basic 程 序 设 计 教 程 魏 东 平 郑 立 垠 梁 玉 环 石 油 大 学 出 版 社 内 容 提 要 本 书 是 按 高 等 学 校 计 算 机 程 序 设 计 课 程 教 学 大 纲 编 写 的 大 学 教 材, 主 要 包 括 VB 基 础 知 识 常 用 程 序 结 构 和 算 法 Windows 用 户 界 面 设 计 基 础 文 件 处
《C语言程序设计》第2版教材习题参考答案
教材 C 语言程序设计 ( 第 2 版 ) 清华大学出版社, 黄保和, 江弋编著 2011 年 10 月第二版 ISBN:978-7-302-26972-4 售价 :35 元 答案版本 本习题答案为 2012 年 2 月修订版本 一 选择题 1. 设已定义 int a, * p, 下列赋值表达式中正确的是 :C)p = &a A. *p = *a B. p = *a C.p = &a D. *p =
《C语言程序设计》教材习题参考答案
教材名称 : C 语言程序设计 ( 第 1 版 ) 黄保和 江弋编著清华大学出版社 ISBN:978-7-302-13599-9, 红色封面 答案制作时间 :2011 年 2 月 -5 月 一 选择题 1. 设已定义 int a, * p, 下列赋值表达式中正确的是 :C)p=&a 2. 设已定义 int x,*p=&x;, 则下列表达式中错误的是 :B)&*x 3. 若已定义 int a=1,*b=&a;,
Bus Hound 5
Bus Hound 5.0 ( 1.0) 21IC 2007 7 BusHound perisoft PC hound Bus Hound 6.0 5.0 5.0 Bus Hound, IDE SCSI USB 1394 DVD Windows9X,WindowsMe,NT4.0,2000,2003,XP XP IRP Html ZIP SCSI sense USB Bus Hound 1 Bus
迅速在两个含有大量数据的文件中寻找相同的数据
迅速在两个含有大量数据的文件中寻找相同的数据 求解问题如下 : 在本地磁盘里面有 file1 和 file2 两个文件, 每一个文件包含 500 万条随机整数 ( 可以重复 ), 最大不超过 2147483648 也就是一个 int 表示范围 要求写程序将两个文件中都含有的整数输出到一个新文件中 要求 : 1. 程序的运行时间不超过 5 秒钟 2. 没有内存泄漏 3. 代码规范, 能要考虑到出错情况
学习MSP430单片机推荐参考书
MSP430 16 MSP430 C MSP430 C MSP430 FLASH 16 1 CPU 16 ALU 16 PC SP SR R4~R15 2 3 00-FFH 100-1FFH 4 5 1 2 51 24 27 6 1 2 3 4 5 6 4 12 SR SP SR CPU SR CPU C Z N GIE CPUOff CPU OscOff SCG0 SCG1 CPU EXIT SP
,768 32,767 32K JMP Jnnn (386+) LOOP CALL [Label:] JMP short/near/far address L10: jmp jmp L20: L10 L20
(Jump) (Loop) (Conditional jump) CMP CALL AND SAR/SHR TEST JMP NOT SAL/SHL Jnnn* OR RCR/ROR LOOP XOR RCL/ROL RETn * nnn, JNE JL -128 127-32,768 32,767 32K JMP Jnnn (386+) LOOP CALL [Label:] JMP short/near/far
untitled
不 料 料 例 : ( 料 ) 串 度 8 年 數 串 度 4 串 度 數 數 9- ( ) 利 數 struct { ; ; 數 struct 數 ; 9-2 數 利 數 C struct 數 ; C++ 數 ; struct 省略 9-3 例 ( 料 例 ) struct people{ char name[]; int age; char address[4]; char phone[]; int
bingdian001.com
TSM12M TSM12 STM8L152C6, STM8L152R8 MSP430F5325 [email protected]! /******************************************************************************* * : TSM12.c * : * : 2013/10/21 * : TSM12, STM8L f(sysclk)
ROP_bamboofox.key
ROP Return Oriented Programming Lays @ BambooFox Who Am I Lays / L4ys / 累死 - l4ys.tw Reverse Engineering BambooFox / HITCON Outline Buffer Overflow ret2libc / ret2text Return Oriented Programming Payload
Lorem ipsum dolor sit amet, consectetuer adipiscing elit
English for Study in Australia 留 学 澳 洲 英 语 讲 座 Lesson 3: Make yourself at home 第 三 课 : 宾 至 如 归 L1 Male: 各 位 朋 友 好, 欢 迎 您 收 听 留 学 澳 洲 英 语 讲 座 节 目, 我 是 澳 大 利 亚 澳 洲 广 播 电 台 的 节 目 主 持 人 陈 昊 L1 Female: 各 位
C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9
201 201 21 ( ) 1. C pa.c, pb.c, 2. C++ pa.cpp, pb.cpp Compilation Error long long cin scanf Time Limit Exceeded 1: A 1 B 1 C 5 D RPG 10 E 10 F 1 G II 1 1 201 201 C 1 # include 2 int main ( void
Windows XP
Windows XP What is Windows XP Windows is an Operating System An Operating System is the program that controls the hardware of your computer, and gives you an interface that allows you and other programs
AVR单片机指令系统.PDF
AVR 4 1 (1) 89 :AT90S1200, ; (2) 90 ( ):Attiny11/12/15/22; 90 = +89 (3) 118 ( ):AT90S2313/2323/2343/2333,/4414/4433/4434/8515/90S8534/8535 ;118 = + 90 ; (4) 121 ( )ATmega603/103; 121 = + 118 ; (5) 130
How to Debug Tuxedo Server printf( Input data is: %s, inputstr); fprintf(stdout, Input data is %s, inputstr); fprintf(stderr, Input data is %s, inputstr); printf( Return data is: %s, outputstr); tpreturn(tpsuccess,
Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc
在 VMWare-5.5+RedHat-9 下建立 本机 QTopia-2.1.1 虚拟平台 张大海 2008-5-9 一 资源下载 1. 需要以下安装包 : tmake-1.13.tar.gz qtopia-free-source-2.1.1.tar.gz qt-embedded-2.3.10-free.tar.gz qt-x11-2.3.2.tar.gz qt-x11-free-3.3.4.tar.gz
9, : Java 19., [4 ]. 3 Apla2Java Apla PAR,Apla2Java Apla Java.,Apla,,, 1. 1 Apla Apla A[J ] Get elem (set A) A J A B Intersection(set A,set B) A B A B
25 9 2008 9 M ICROEL ECTRON ICS & COMPU TER Vol. 25 No. 9 September 2008 J ava 1,2, 1,2, 1,2 (1, 330022 ; 2, 330022) :,. Apla - Java,,.. : PAR ;Apla - Java ; ;CMP ; : TP311 : A : 1000-7180 (2008) 09-0018
untitled
1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override
Untitiled
目 立人1 2011 录 目 录 专家视点 权利与责任 班主任批评权的有效运用 齐学红 3 德育园地 立 沿着鲁迅爷爷的足迹 主题队活动案例 郑海娟 4 播下一颗美丽的种子 沿着鲁迅爷爷的足迹 中队活动反思 郑海娟 5 赠人玫瑰 手有余香 关于培养小学生服务意识的一些尝试和思考 孙 勤 6 人 教海纵横 2011 年第 1 期 总第 9 期 主办单位 绍兴市鲁迅小学教育集团 顾 问 编委会主任 编
Spyder Anaconda Spyder Python Spyder Python Spyder Spyder Spyder 開始 \ 所有程式 \ Anaconda3 (64-bit) \ Spyder Spyder IPython Python IPython Sp
01 1.6 Spyder Anaconda Spyder Python Spyder Python Spyder Spyder 1.6.1 Spyder 開始 \ 所有程式 \ Anaconda3 (64-bit) \ Spyder Spyder IPython Python IPython Spyder Python File
CC213
: (Ken-Yi Lee), E-mail: [email protected] 9 [P.11] : Dev C++ [P.12] : http://c.feis.tw [P.13] [P.14] [P.15] [P.17] [P.23] Dev C++ [P.24] [P.27] [P.34] C / C++ [P.35] 10 C / C++ C C++ C C++ C++ C ( ) C++
untitled
A, 3+A printf( ABCDEF ) 3+ printf( ABCDEF ) 2.1 C++ main main main) * ( ) ( ) [ ].* ->* ()[] [][] ** *& char (f)(int); ( ) (f) (f) f (int) f int char f char f(int) (f) char (*f)(int); (*f) (int) (
《计算概论》课程 第十九讲 C 程序设计语言应用
计算概论 A 程序设计部分 字符数组与字符串 李戈 北京大学信息科学技术学院软件研究所 [email protected] 字符数组的定义 #include int main() char a[10] = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ; for (int i = 0; i < 10; i++) cout
Simulator By SunLingxi 2003
Simulator By SunLingxi [email protected] 2003 windows 2000 Tornado ping ping 1. Tornado Full Simulator...3 2....3 3. ping...6 4. Tornado Simulator BSP...6 5. VxWorks simpc...7 6. simulator...7 7. simulator
全国计算机技术与软件专业技术资格(水平)考试
全 国 计 算 机 技 术 与 软 件 专 业 技 术 资 格 ( 水 平 ) 考 试 2008 年 上 半 年 程 序 员 下 午 试 卷 ( 考 试 时 间 14:00~16:30 共 150 分 钟 ) 试 题 一 ( 共 15 分 ) 阅 读 以 下 说 明 和 流 程 图, 填 补 流 程 图 中 的 空 缺 (1)~(9), 将 解 答 填 入 答 题 纸 的 对 应 栏 内 [ 说 明
AL-M200 Series
NPD4754-00 TC ( ) Windows 7 1. [Start ( )] [Control Panel ()] [Network and Internet ( )] 2. [Network and Sharing Center ( )] 3. [Change adapter settings ( )] 4. 3 Windows XP 1. [Start ( )] [Control Panel
静态分析 投放文件 行为分析 互斥量 (Mutexes) 执行的命令 创建的服务 启动的服务 进程 cmd.exe PID: 2520, 上一级进程 PID: 2556 cmd.exe PID: 2604, 上一级进程 PID: 2520 访问的文件 C:\Users\test\AppData\Lo
魔盾安全分析报告 分析类型 开始时间 结束时间 持续时间 分析引擎版本 FILE 2016-11-25 00:20:03 2016-11-25 00:22:18 135 秒 1.4-Maldun 虚拟机机器名 标签 虚拟机管理 开机时间 关机时间 win7-sp1-x64 win7-sp1-x64 KVM 2016-11-25 00:20:03 2016-11-25 00:22:18 魔盾分数 0.0
Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]
Arrays and Strings 存储同类型的多个元素 Store multi elements of the same type 数组 (array) 存储固定数目的同类型元素 如整型数组存储的是一组整数, 字符数组存储的是一组字符 数组的大小称为数组的尺度 (dimension). 定义格式 : type arrayname[dimension]; 如声明 4 个元素的整型数组 :intarr[4];
C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha
CYPOK CYPOK 1 UltraEdit Project-->Install Language Tool: Language Suite----->hi-tech picc Tool Name ---->PICC Compiler Executable ---->c:hi-picinpicc.exe ( Command-line Project-->New Project-->File Name--->myc
通过Hive将数据写入到ElasticSearch
我在 使用 Hive 读取 ElasticSearch 中的数据 文章中介绍了如何使用 Hive 读取 ElasticSearch 中的数据, 本文将接着上文继续介绍如何使用 Hive 将数据写入到 ElasticSearch 中 在使用前同样需要加入 elasticsearch-hadoop-2.3.4.jar 依赖, 具体请参见前文介绍 我们先在 Hive 里面建个名为 iteblog 的表,
2 12
SHENZHEN BRILLIANT CRYSTAL TECHNOLOGIC CO.,LTD. The specification for the following models Graphic LCM serial communication control board CB001 PROPOSED BY APPROVED Design Approved TEL:+86-755-29995238
chap07.key
#include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,
C/C++语言 - 分支结构
C/C++ Table of contents 1. if 2. if else 3. 4. 5. 6. continue break 7. switch 1 if if i // colddays.c: # include int main ( void ) { const int FREEZING = 0; float temperature ; int cold_ days
6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit
6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C51 6.1 C51 6.1.1 C51 C51 ANSI C MCS-51 C51 ANSI C C51 6.1 6.1 C51 bit Byte bit sbit 1 0 1 unsigned char 8 1 0 255 Signed char 8 11 128
Microsoft Word zw
第 1 章 Android 概述 学习目标 : Android Android Android Studio Android Android APK 1.1 1. 智能手机的定义 Smartphone 2. 智能手机的发展 1973 4 3 PC IBM 1994 IBM Simon PDA PDA Zaurus OS 1996 Nokia 9000 Communicator Nokia 9000
1 CPU interrupt INT trap CPU exception
1 CPU interrupt INT trap CPU exception 2 X86 CPU gate 64 16 1 2 5 8 16 16 P DPL 00101 TSS 101 DPL P 1 64 16 1 2 1 1 3 3 5 16 16 16 P DPL 0 D 000 16 110 111 100 D 1=32 0=16 DPL P 1 INT DPL1>=CPL>=DPL CPU
TX-NR3030_BAS_Cs_ indd
TX-NR3030 http://www.onkyo.com/manual/txnr3030/adv/cs.html Cs 1 2 3 Speaker Cable 2 HDMI OUT HDMI IN HDMI OUT HDMI OUT HDMI OUT HDMI OUT 1 DIGITAL OPTICAL OUT AUDIO OUT TV 3 1 5 4 6 1 2 3 3 2 2 4 3 2 5
1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10
Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1
untitled
1 Outline 料 類 說 Tang, Shih-Hsuan 2006/07/26 ~ 2006/09/02 六 PM 7:00 ~ 9:30 聯 [email protected] www.csie.ntu.edu.tw/~r93057/aspnet134 度 C# 力 度 C# Web SQL 料 DataGrid DataList 參 ASP.NET 1.0 C# 例 ASP.NET 立
目 录
1 Quick51...1 1.1 SmartSOPC Quick51...1 1.2 Quick51...1 1.3 Quick51...2 2 Keil C51 Quick51...4 2.1 Keil C51...4 2.2 Keil C51...4 2.3 1 Keil C51...4 2.4 Flash Magic...9 2.5 ISP...9 2.6...10 2.7 Keil C51...12
Outline USB Application Requirements Variable Definition Communications Code for VB Code for Keil C Practice
路 ESW 聯 USB Chapter 9 Applications For Windows Outline USB Application Requirements Variable Definition Communications Code for VB Code for Keil C Practice USB I/O USB / USB 3 料 2 1 3 路 USB / 列 料 料 料 LED
C
C 2017 4 1 1. 2. while 3. 4. 5. for 6. 2/161 C 7. 8. (do while) 9. 10. (nested loop) 11. 12. 3/161 C 1. I 1 // summing.c: 2 #include 3 int main(void) 4 { 5 long num; 6 long sum = 0L; 7 int status;
instructions.PDF
94 SIMATIC (END) (END) Micro/WIN 32 (STOP) (STOP) CPU RUN STOP STOP CPU RUN STOP (WDR) (Watchdog Reset) (WDR) CPU WDR WDR ( ) I/O ( I/O ) SM (SM0 SM5 SM29 ) 25 0 ms 00 ms STOP 300ms 300ms WDR S7-200 CPU
Microsoft Word - QTP测试Flex.doc
TIB 自动化测试工作室 http://www.cnblogs.com/testware 使用 QTP 进行 Flex 自动化测试 自动化测试工具与 Flex 应用程序之间是通过代理 (Agent) 来交互的, 如图所示 : 这也就是为什么后面在使用 QTP 进行 Flex 自动化测试之前要先安装 Flex 插件 配置和编译 Flex 程序的原因 前提条件 在使用 QTP 进行 Flex 4 的测试之前,
27 :OPC 45 [4] (Automation Interface Standard), (Costom Interface Standard), OPC 2,,, VB Delphi OPC, OPC C++, OPC OPC OPC, [1] 1 OPC 1.1 OPC OPC(OLE f
27 1 Vol.27 No.1 CEMENTED CARBIDE 2010 2 Feb.2010!"!!!!"!!!!"!" doi:10.3969/j.issn.1003-7292.2010.01.011 OPC 1 1 2 1 (1., 412008; 2., 518052), OPC, WinCC VB,,, OPC ; ;VB ;WinCC Application of OPC Technology
1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F
1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET 2.0 2.0.NET Framework.NET Framework 2.0 ( 3).NET Framework 2.0.NET Framework ( System ) o o o o o o Boxing UnBoxing() o
res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml
拓展训练 1- 界面布局 1. 界面布局的重要性做应用程序, 界面是最基本的 Andorid 的界面, 需要写在 res/layout 的 xml 里面, 一般情况下一个 xml 对应一个界面 Android 界面布局有点像写 html( 连注释代码的方式都一样 ), 要先给 Android 定框架, 然后再在框架里面放控件,Android 提供了几种框架,AbsoluteLayout,LinearLayout,
目 錄 壹 青 輔 會 結 案 附 件 貳 活 動 計 劃 書 參 執 行 內 容 一 教 學 內 容 二 與 當 地 教 師 教 學 交 流 三 服 務 執 行 進 度 肆 執 行 成 效 一 教 學 課 程 二 與 當 地 教 師 教 學 交 流 三 服 務 滿 意 度 調 查 伍 服 務 檢
2 0 1 0 年 靜 宜 青 年 國 際 志 工 泰 北 服 務 成 果 報 告 指 導 單 位 : 行 政 院 青 年 輔 導 委 員 會 僑 務 委 員 會 主 辦 單 位 : 靜 宜 大 學 服 務 學 習 發 展 中 心 協 力 單 位 : 靜 宜 大 學 師 資 培 育 中 心 財 團 法 人 台 灣 明 愛 文 教 基 金 會 中 華 民 國 九 十 九 年 九 月 二 十 四 日 目
JavaIO.PDF
O u t p u t S t ream j a v a. i o. O u t p u t S t r e a m w r i t e () f l u s h () c l o s e () public abstract void write(int b) throws IOException public void write(byte[] data) throws IOException
<4D F736F F D20C9EEDBDACAD0BAA3D4C2CDA8D0C5B6AFCCACC3DCC2EBBDE2BEF6B7BDB0B82E646F63>
深 圳 市 海 月 通 信 技 术 有 限 公 司 动 态 密 码 解 决 方 案 建 议 书 深 圳 市 海 月 通 信 技 术 有 限 公 司 深 圳 市 海 月 通 信 技 术 有 限 公 司 第 1 页 ( 共 25 页 ) 目 录 1. 方 案 背 景... 3 2. 动 态 密 码 解 决 方 案 介 绍... 5 2.1. 动 态 密 码 系 统 介 绍... 5 2.1.1. 动 态
一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页
第 1 页共 32 页 crm Mobile V1.0 for IOS 用户手册 一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 二 crm Mobile 界面介绍 : 第 3 页共 32 页 三 新建 (New) 功能使用说明 1 选择产品 第 4 页共 32 页 2 填写问题的简要描述和详细描述 第 5 页共
OOP with Java 通知 Project 4: 4 月 19 日晚 9 点
OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d
C++ 程式設計
C C 料, 數, - 列 串 理 列 main 數串列 什 pointer) 數, 數, 數 數 省 不 不, 數 (1) 數, 不 數 * 料 * 數 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr; 數 (2) int i=3; int *ptr; ptr=&i; 1000 1012 ptr 數, 數 1004
epub83-1
C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C
TwinCAT 1. TwinCAT TwinCAT PLC PLC IEC TwinCAT TwinCAT Masc
TwinCAT 2001.12.11 TwinCAT 1. TwinCAT... 3 2.... 4... 4...11 3. TwinCAT PLC... 13... 13 PLC IEC 61131-3... 14 4. TwinCAT... 17... 17 5. TwinCAT... 18... 18 6.... 19 Maschine.pro... 19... 27 7.... 31...
MASQUERADE # iptables -t nat -A POSTROUTING -s / o eth0 -j # sysctl net.ipv4.ip_forward=1 # iptables -P FORWARD DROP #
iptables 默认安全规则脚本 一 #nat 路由器 ( 一 ) 允许路由 # iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT ( 二 ) DNAT 与端口转发 1 启用 DNAT 转发 # iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 dprot 422 -j DNAT to-destination
Microsoft Word - CPE考生使用手冊160524.docx
大 學 程 式 能 力 檢 定 (CPE) 考 生 使 用 手 冊 2016 年 5 月 24 日 這 份 手 冊 提 供 給 參 加 CPE 檢 定 考 試 的 考 生 內 容 包 含 考 試 環 境 的 使 用, 以 及 解 題 時 所 使 用 I/O 的 基 本 知 識 1. 如 欲 報 名 參 加 CPE 考 試, 請 先 於 CPE 網 站 完 成 帳 號 註 冊, 然 後 再 報 名 該
untitled
2006 6 Geoframe Geoframe 4.0.3 Geoframe 1.2 1 Project Manager Project Management Create a new project Create a new project ( ) OK storage setting OK (Create charisma project extension) NO OK 2 Edit project
