2024 强网杯逆向 Writeups

news/2024/11/7 4:37:09/文章来源:https://www.cnblogs.com/gaoyucan/p/18524224

最心有余而力不足的一集,做完 vm 颈椎病犯了,第二天根本打。最后,加上学弟学妹打的,最后剩一个 Android 逆向没 AK,要是没有颈椎病这一说肯定 AK 了。感觉快退役了...

mips

编译一个 qemu-6.2.0 mips-linux-user bindiff 一下恢复符号,怀疑修改了 ELF loader 或者 syscall,最后发现是后者改了 do_syscall1 函数 read 和 write 系统调用实现。交叉引用找到加密算法
image

//
// Created by gaoyucan on 2024/11/2.
//
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>uint8_t *decrypt_func(const uint8_t *buf) {uint8_t sbox[256] = {0};unsigned char key_arr[4] = {0xDE, 0xAD, 0xBE, 0xEF};for (int i = 0; i < 256; ++i) {sbox[i] = i;}const char *key = "6105t3";int v5 = 0;for (int i = 0; i < 256; ++i) {uint8_t a = sbox[i];uint8_t b = key[i % 6];v5 += a + b;sbox[i] = sbox[v5 & 0xff];sbox[v5 & 0xff] = a;}uint8_t *ret = malloc(256);memset(ret, 0, 256);int v7 = 0;int v8 = 0;for (int i = 0; i < 22; ++i) {v7 += 1;uint8_t a = sbox[v7 & 0xff];v8 += a;sbox[v7 & 0xff] = sbox[v8 & 0xff];sbox[v8 & 0xff] = a;uint8_t t = sbox[0xff & (sbox[v7 & 0xff] + a)] ^ key_arr[i & 0x3] ^ buf[i];t = ((t << 5 | t >> 3) & 0xff) ^ 0xde;t = ((t << 4 | t >> 4) & 0xff) ^ 0xad;t = ((t << 3 | t >> 5) & 0xff) ^ 0xbe;t ^= (0x3b | 0xc0);t = ((t << 2 | t >> 6) & 0xff);t = ((t << 1 | t >> 7) & 0xff);ret[i] = t;}return ret;
}int swap(uint8_t *buf, int a, int b) {uint8_t tmp = buf[a];buf[a] = buf[b];buf[b] = tmp;return 0;
}int main() {uint8_t dest_value[24] = {0x000000C4, 0x000000EE, 0x0000003C, 0x000000BB, 0x000000E7, 0x000000FD, 0x00000067, 0x0000001D,0x000000F8, 0x00000097, 0x00000068, 0x0000009D, 0x0000000B, 0x0000007F, 0x000000C7, 0x00000080,0x000000DF, 0x000000F9, 0x0000004B, 0x000000A0, 0x00000046, 0x00000091, 0x00000000, 0x00000000};swap(dest_value, 7, 11);swap(dest_value, 12, 16);for (int i = 0; i < 22; ++i) {dest_value[i] ^= 0xa;}uint8_t *ret = decrypt_func(dest_value);printf("%s\n", ret);for (int i = 0; i < 22; ++i) {printf("%02X ", ret[i]);}return 0;
}

ez_vm

虚拟机 + 白盒 AES

虚拟机是个栈虚拟机,指令看起来就是从 x64 汇编翻译过来的,下面是反编译脚本,前面手开头的要手动处理一下,也没几个 replace 替换一下即可

import math
from capstone import *
from capstone.x86_const import *
from vm_const import *
import ctypesclass Operand(object):def __init__(self, size):self.size = sizeclass Imm(Operand):def __init__(self, val, size):super().__init__(size)self.val = valdef __str__(self):return hex(self.val)properties_map = {0x00000010: ["rax", "eax", "ax", "al"],0x00000018: ["rcx", "ecx", "cx", "cl"],0x00000020: ["rdx", "edx", "dx", "dl"],0x00000028: ["rbx", "ebx", "bx", "bl"],0x00000030: ["rsp", "esp", "sp", "spl"],0x00000038: ["rbp", "ebp", "bp", "bpl"],0x00000040: ["rsi", "esi", "si", "sil"],0x00000048: ["rdi", "edi", "di", "dil"],0x00000050: ["r8", "r8d", "r8w", "r8b"],0x00000058: ["r9", "r9d", "r9w", "r9b"],0x00000060: ["r10", "r10d", "r10w", "r10b"],0x00000068: ["r11", "r11d", "r11w", "r11b"],0x00000070: ["r12", "r12d", "r12w", "r12b"],0x00000078: ["r13", "r13d", "r13w", "r13b"],0x00000080: ["r14", "r14d", "r14w", "r14b"],0x00000088: ["r15", "r15d", "r15w", "r15b"]
}size_map = {1: "byte",2: "word",4: "dword",8: "qword"
}class RegPtr(Operand):def __init__(self, name_arr, size=8):super().__init__(size)self.name_arr = name_arrclass Reg(Operand):def __init__(self, reg_ptr: RegPtr, size):super().__init__(size)self.name = reg_ptr.name_arr[3 - int(math.log2(size))]def __str__(self):return self.nameclass VMPtr(Operand):def __init__(self):super().__init__(8)def get_property(self, offset):return RegPtr(properties_map[offset])class SExp(Operand):def __init__(self, op, operand1, size):super().__init__(size)self.op = opself.operand1 = operand1def __str__(self):return f'{self.op}({self.operand1})'class BExp(Operand):def __init__(self, op, operand1, operand2, size):super().__init__(size)self.op = opself.operand1 = operand1self.operand2 = operand2def __str__(self):return f'({self.operand2}) {self.op} ({self.operand1})'class LoadExp(Operand):def __init__(self, exp: BExp | Reg, size):super().__init__(size)if isinstance(exp, Reg):self.complex = 0self.base = expreturnassert exp.op == 'add' and isinstance(exp.operand1, Imm);self.disp = exp.operand1.valif isinstance(exp.operand2, BExp):self.complex = 2exp_inner = exp.operand2assert exp_inner.op == 'add' and isinstance(exp_inner.operand2, Reg);self.base = exp_inner.operand2exp_offset = exp_inner.operand1assert isinstance(exp_offset, BExp) and exp_offset.op == 'imul';self.offset = exp_offset.operand2self.scale = exp_offset.operand1else:self.complex = 1self.base = exp.operand2def __str__(self):if self.complex == 2:return f'{size_map[self.size]} ptr [{self.base} + {self.offset} * {self.scale} + 0x{self.disp:x}]'elif self.complex == 1:return f'{size_map[self.size]} ptr [{self.base} + 0x{self.disp:x}]'else:return f'{size_map[self.size]} ptr [{self.base}]'class VM(object):def __init__(self, buffer: bytes):self.buffer = bufferself.cs = Cs(CS_ARCH_X86, CS_MODE_64)self.stack = []self.name_idx = 0def next_temp_name(self):name = f't_{self.name_idx}'self.name_idx += 1return namedef disassemble(self, offset):"""注意:push 和 pop 至少是 2bytes,  所有 u8 都必须复用 u16 的代码:param offset::return:"""opcode = self.buffer[offset]opcode_b = self.buffer[offset + 1]# 校验 opcode 和 opcode_bassert opcode <= 29 and opcode_b <= 8opcode_size = 2is_end = Falsematch opcode:case 0:# pushoperand = int.from_bytes(self.buffer[offset + 2:offset + 2 + opcode_b], "little")# print(f'{offset:08x}: push_u{opcode_b * 8} {operand:08x}')self.stack.append(Imm(operand, opcode_b))opcode_size += opcode_bcase 1:# load => push(*pop())A = self.stack.pop()if isinstance(A, RegPtr):self.stack.append(Reg(A, opcode_b))else:assert isinstance(A, BExp) or isinstance(A, Reg)self.stack.append(LoadExp(A, opcode_b))case 2:# load_u128raise "not impl"case 3 | 5 | 6:  # 看起来 3 和 5 完全一样# store => A = pop(); *A = pop()A = self.stack.pop()B = self.stack.pop()if isinstance(A, RegPtr):A = Reg(A, opcode_b)if isinstance(B, BExp):if not isinstance(B.operand2, Reg):print(f'{offset:08x}: 手 {A} = {B}')elif A.name == B.operand2.name:print(f'{offset:08x}: {B.op} {A}, {B.operand1}')else:print(f'{offset:08x}: 手 {A} = {B}')else:print(f'{offset:08x}: mov {A}, {B}')else:assert isinstance(A, BExp) or isinstance(A, Reg)A = LoadExp(A, opcode_b)print(f'{offset:08x}: mov {A}, {B}')case 4:# store_u128raise "not impl"case 7:# addA = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('add', A, B, opcode_b))case 8:# subA = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('sub', A, B, opcode_b))case 9:raise "not impl"case 10:raise "not impl"case 11:A = self.stack.pop()B = self.stack.pop()if isinstance(A, Imm) and A.val == 2:self.stack.append(BExp('shr', Imm(1, 8), B, opcode_b))else:raise "not impl"case 12:raise "not impl"case 13:A = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('imul', A, B, opcode_b))case 14:A = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('and', A, B, opcode_b))case 15:A = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('or', A, B, opcode_b))case 16:A = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('xor', A, B, opcode_b))case 17:A = self.stack.pop()self.stack.append(SExp('not', A, opcode_b))case 18:A = self.stack.pop()B = self.stack.pop()assert len(self.stack) == 0print(f'{offset:08x}: cmp {B}, {A}')case 19 | 20:assert opcode_b == 2raise "not impl"case 21:cond = self.buffer[offset + 2]if cond == 0:cond = 'mp'if cond == 5:cond = 'ge'operand = int.from_bytes(self.buffer[offset + 3:offset + 3 + 8], "little")operand = ctypes.c_int64(operand).valueprint(f'{offset:08x}: j{cond} label_{offset - operand:08x}')opcode_size += 8 + 1case 22:# push_vm VM_ptrself.stack.append(VMPtr())case 23:# addA = self.stack.pop()B = self.stack.pop()if isinstance(B, VMPtr) and isinstance(A, Imm):self.stack.append(B.get_property(A.val))else:self.stack.append(BExp('add', A, B, opcode_b))case 24:# mulA = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('imul', A, B, opcode_b))case 25:# subA = self.stack.pop()B = self.stack.pop()self.stack.append(BExp('sub', A, B, opcode_b))case 26:# do nothingoperand = int.from_bytes(self.buffer[offset + 2:offset + 2 + opcode_b], "little")opcode_size += opcode_bcase 27:operand1 = self.buffer[offset + 2]shellcode = self.buffer[offset + 3: offset + 3 + operand1]shellcode = '\r\n' + '\r\n'.join(str(ins) for ins in self.cs.disasm(shellcode, 0))print(f'{offset:08x}: run_shellcode {shellcode}')opcode_size = operand1 + 3case 28:print(f'{offset:08x}: return')is_end = Truecase _:print(f'{offset:08x}: unk_opcode {opcode}')is_end = Truereturn opcode_size, is_endvm = VM(bytes.fromhex(code))off = 0while True:size_of_op, is_end = vm.disassemble(off)if is_end:breakoff += size_of_op

反编译完 jmp 指令的目标地址对不上了,要修一下:

import rea = re.compile('jmp label_([a-f0-9]+)')
b = re.compile('jge label_([a-f0-9]+)')with open('./x86.txt', 'rb') as f:content = f.read().decode('utf8')label_arr = a.findall(content)
label_arr += b.findall(content)label_arr = [int(_, 16) for _ in label_arr]
label_arr.sort()idx = 0
lines = content.split('\r\n')
c = re.compile('([a-f0-9]+): (.+)')
with open('./x86_fix.txt', 'wb') as f:for line in lines:m = c.match(line)if m is None:f.write(b'\t' + line.encode() + b'\r\n')continueif idx < len(label_arr):addr = int(m.group(1), 16)if addr >= label_arr[idx]:f.write(f'label_{label_arr[idx]:08x}:'.encode() + b'\r\n')idx += 1f.write(b'\t' + m.group(2).encode() + b'\r\n')

修复完之后,手动调整一下格式,nasm 编译一下(要去掉 ptr,写反编译的时候按 masm 写的,但是发现 masm 一堆逼事,转而使用 nasm),编译成功之后得到源码般的享受,发现是白盒AES

image

dump 出来常量表

from idaapi import *
def get_TyiBoxes(base_addr):with open(f'TyiBoxes_{base_addr:x}', 'wb') as f:size = 256 * 4 * 16 * 9content = get_bytes(base_addr, size)f.write(content)def get_TBoxs(base_addr):with open(f'TBoxs_{base_addr:x}', 'wb') as f:size = 256 * 16 * 10content = get_bytes(base_addr, size)f.write(content)def get_mixBijOut(base_addr):with open(f'mixBijOut_{base_addr:x}', 'wb') as f:size = 256 * 4 * 16 * 10content = get_bytes(base_addr, size)f.write(content)get_TyiBoxes(0x140013000)
get_TBoxs(0x140011000 - 9 * 16 * 256)
get_mixBijOut(0x140037000)

DFA 攻击

//
// Created by gaoyucan on 2024/11/2.
//#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>#define ROTL8(x, shift) ((u8) ((x) << (shift)) | ((x) >> (8 - (shift))))typedef unsigned char u8;
typedef unsigned int u32;
u8 DFA = 0;u8 xorTable[9][96][16][16];
u32 TyiBoxes[9][16][256];
unsigned char TBoxes[10][16][256];
unsigned int mixBijOut[10][16][256];void GetxorTable() {for (int i = 0; i < 9; i++) {for (int j = 0; j < 96; j++) {for (int x = 0; x < 16; x++) { //2的4次方=16for (int y = 0; y < 16; y++) {xorTable[i][j][x][y] = x ^ y;}}}}
}void shiftRows(u8 state[16]) {u8 out[16];int shiftTab[16] = {0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11};for (int i = 0; i < 16; i++) {out[i] = state[shiftTab[i]];}memcpy(state, out, sizeof(out));
}void AES_128_encrypt(unsigned char ciphertext[16], unsigned char plaintext[16]) {u8 input[16] = {0};u8 output[16] = {0};memcpy(input, plaintext, 16);u32 a, b, c, d, aa, bb, cc, dd;for (int i = 0; i < 9; i++) {// DFA Attackif (DFA && i == 8) {input[rand() % 16] = rand() % 256;}shiftRows(input);for (int j = 0; j < 4; j++) {a = TyiBoxes[i][4 * j + 0][input[4 * j + 0]];b = TyiBoxes[i][4 * j + 1][input[4 * j + 1]];c = TyiBoxes[i][4 * j + 2][input[4 * j + 2]];d = TyiBoxes[i][4 * j + 3][input[4 * j + 3]];aa = xorTable[i][24 * j + 0][(a >> 28) & 0xf][(b >> 28) & 0xf];bb = xorTable[i][24 * j + 1][(c >> 28) & 0xf][(d >> 28) & 0xf];cc = xorTable[i][24 * j + 2][(a >> 24) & 0xf][(b >> 24) & 0xf];dd = xorTable[i][24 * j + 3][(c >> 24) & 0xf][(d >> 24) & 0xf];input[4 * j + 0] = (xorTable[i][24 * j + 4][aa][bb] << 4) | xorTable[i][24 * j + 5][cc][dd];aa = xorTable[i][24 * j + 6][(a >> 20) & 0xf][(b >> 20) & 0xf];bb = xorTable[i][24 * j + 7][(c >> 20) & 0xf][(d >> 20) & 0xf];cc = xorTable[i][24 * j + 8][(a >> 16) & 0xf][(b >> 16) & 0xf];dd = xorTable[i][24 * j + 9][(c >> 16) & 0xf][(d >> 16) & 0xf];input[4 * j + 1] = (xorTable[i][24 * j + 10][aa][bb] << 4) | xorTable[i][24 * j + 11][cc][dd];aa = xorTable[i][24 * j + 12][(a >> 12) & 0xf][(b >> 12) & 0xf];bb = xorTable[i][24 * j + 13][(c >> 12) & 0xf][(d >> 12) & 0xf];cc = xorTable[i][24 * j + 14][(a >> 8) & 0xf][(b >> 8) & 0xf];dd = xorTable[i][24 * j + 15][(c >> 8) & 0xf][(d >> 8) & 0xf];input[4 * j + 2] = (xorTable[i][24 * j + 16][aa][bb] << 4) | xorTable[i][24 * j + 17][cc][dd];aa = xorTable[i][24 * j + 18][(a >> 4) & 0xf][(b >> 4) & 0xf];bb = xorTable[i][24 * j + 19][(c >> 4) & 0xf][(d >> 4) & 0xf];cc = xorTable[i][24 * j + 20][(a >> 0) & 0xf][(b >> 0) & 0xf];dd = xorTable[i][24 * j + 21][(c >> 0) & 0xf][(d >> 0) & 0xf];input[4 * j + 3] = (xorTable[i][24 * j + 22][aa][bb] << 4) | xorTable[i][24 * j + 23][cc][dd];a = mixBijOut[i][4 * j + 0][input[4 * j + 0]];b = mixBijOut[i][4 * j + 1][input[4 * j + 1]];c = mixBijOut[i][4 * j + 2][input[4 * j + 2]];d = mixBijOut[i][4 * j + 3][input[4 * j + 3]];aa = xorTable[i][24 * j + 0][(a >> 28) & 0xf][(b >> 28) & 0xf];bb = xorTable[i][24 * j + 1][(c >> 28) & 0xf][(d >> 28) & 0xf];cc = xorTable[i][24 * j + 2][(a >> 24) & 0xf][(b >> 24) & 0xf];dd = xorTable[i][24 * j + 3][(c >> 24) & 0xf][(d >> 24) & 0xf];input[4 * j + 0] = (xorTable[i][24 * j + 4][aa][bb] << 4) | xorTable[i][24 * j + 5][cc][dd];aa = xorTable[i][24 * j + 6][(a >> 20) & 0xf][(b >> 20) & 0xf];bb = xorTable[i][24 * j + 7][(c >> 20) & 0xf][(d >> 20) & 0xf];cc = xorTable[i][24 * j + 8][(a >> 16) & 0xf][(b >> 16) & 0xf];dd = xorTable[i][24 * j + 9][(c >> 16) & 0xf][(d >> 16) & 0xf];input[4 * j + 1] = (xorTable[i][24 * j + 10][aa][bb] << 4) | xorTable[i][24 * j + 11][cc][dd];aa = xorTable[i][24 * j + 12][(a >> 12) & 0xf][(b >> 12) & 0xf];bb = xorTable[i][24 * j + 13][(c >> 12) & 0xf][(d >> 12) & 0xf];cc = xorTable[i][24 * j + 14][(a >> 8) & 0xf][(b >> 8) & 0xf];dd = xorTable[i][24 * j + 15][(c >> 8) & 0xf][(d >> 8) & 0xf];input[4 * j + 2] = (xorTable[i][24 * j + 16][aa][bb] << 4) | xorTable[i][24 * j + 17][cc][dd];aa = xorTable[i][24 * j + 18][(a >> 4) & 0xf][(b >> 4) & 0xf];bb = xorTable[i][24 * j + 19][(c >> 4) & 0xf][(d >> 4) & 0xf];cc = xorTable[i][24 * j + 20][(a >> 0) & 0xf][(b >> 0) & 0xf];dd = xorTable[i][24 * j + 21][(c >> 0) & 0xf][(d >> 0) & 0xf];input[4 * j + 3] = (xorTable[i][24 * j + 22][aa][bb] << 4) | xorTable[i][24 * j + 23][cc][dd];}}shiftRows(input);for (int j = 0; j < 16; j++) {input[j] = TBoxes[9][j][input[j]];}for (int i = 0; i < 16; i++)output[i] = input[i];memcpy(ciphertext, output, 16);}void readBoxes() {const char *PATH1 = "C:\\Users\\gaoyucan\\Desktop\\temp\\qwb\\ez_vm_a1774a181b73b74e6428c2c80ecf6b63\\TyiBoxes_140013000";FILE *fp = fopen(PATH1, "rb");fread(TyiBoxes, sizeof(TyiBoxes), 1, fp);fclose(fp);const char *PATH2 = "C:\\Users\\gaoyucan\\Desktop\\temp\\qwb\\ez_vm_a1774a181b73b74e6428c2c80ecf6b63\\TBoxs_140008000";fp = fopen(PATH2, "rb");fread(TBoxes, sizeof(TBoxes), 1, fp);fclose(fp);const char *PATH3 = "C:\\Users\\gaoyucan\\Desktop\\temp\\qwb\\ez_vm_a1774a181b73b74e6428c2c80ecf6b63\\mixBijOut_140037000";fp = fopen(PATH3, "rb");fread(mixBijOut, sizeof(mixBijOut), 1, fp);fclose(fp);
}int main() {srand(time(0));GetxorTable();readBoxes();for (int i = 0; i < 32; ++i) {DFA = i != 0;char flag[16] = {0};memset(flag, 0x11, 16);unsigned char ciphertext[16] = {0};AES_128_encrypt(ciphertext, flag);for (int i = 0; i < 16; ++i) {printf("%02X", ciphertext[i]);}puts("");}return 0;
}

phoenixAES 恢复出来最后一轮密钥

import phoenixAESdata = """0A4A2B9BF7BF167B758998590B7B415F
0A4A2B98F7BF177B75129859137B415F
0A4A029BF718167B848998590B7B4142
624A2B9BF7BF16CF7589B1590B4C415F
934A2B9BF7BF16F5758912590B3E415F
044A2B9BF7BF1642758908590B7D415F
A94A2B9BF7BF16ED75895C590B45415F
564A2B9BF7BF161B7589BB590BE5415F
0A4AED9BF722167BD18998590B7B4152
0A982B9B39BF167B758998250B7B4E5F
0A4A2BEEF7BFDB7B75259859BA7B415F
0A4A2BD8F7BFC77B759098596F7B415F
0A4A2BE0F7BF097B75A59859A77B415F
0A732B9B94BF167B758998450B7BDE5F
0AA22B9B77BF167B758998FB0B7BE85F
0A4A2BB3F7BF607B75799859D57B415F
0AE72B9B44BF167B758998B40B7B465F
0A4A2B50F7BFCB7B75469859BF7B415F
0A4ACA9BF794167BD28998590B7B41C7
0A4A229BF75C167B598998590B7B415C
0A4A2B17F7BFD27B75C198598B7B415F
0A932B9B67BF167B758998B00B7BAA5F
0A4AC19BF702167BC68998590B7B4181
E34A2B9BF7BF164E758929590B70415F
0A4AAB9BF710167B798998590B7B4158
0A572B9BFEBF167B758998E70B7BFC5F
0A4A2B80F7BFC07B750098595F7B415F
0A4AD09BF7BC167B2D8998590B7B41BE
0A4A2B63F7BF727B75D698598B7B415F
0A4A2B21F7BFE47B75BD9859117B415F
0A4A2B80F7BFC07B750098595F7B415F
504A2B9BF7BF16C7758900590BC5415F
"""with open('crackfile', 'w') as fp:fp.write(data)
phoenixAES.crack_file('crackfile', [], True, False, verbose=2)

Stark 恢复密钥
image

Cyberchef 解一下

image

remem

VM 很简单解出来 5 个方程,使用 SageMath 求解一下
image

from Crypto.Util.number import long_to_bytesx1 = 862152290
x2 = 53932501 + 0x5E2F4391
x3 = 962670904
x4 = 859320929
x5 = 50524140 + 0x5E2F4391
print(long_to_bytes(x1) + long_to_bytes(x2) + long_to_bytes(x3) + long_to_bytes(x4) + long_to_bytes(x5))# 2*x1*x1 + 13*x2 + 17*x1
# 5*x3*x3 + 88*x3 + 4294967291*x1*x3
# 5*x3*x3 + 232*x4 -4*x3*x4
# 8*x5 + 16*x5*x5 -0x23*x4*x4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/826405.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

坐标系-投影

墨卡托投影墨卡托投影(Mercator Projection),是正轴等角圆柱投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假设地球被围在一中空的圆柱里,其基准纬线与圆柱相切(赤道)接触,然后再假想地球中心有一盏灯,把球面上的图形投影到圆柱体上,再把圆柱体展开,这就是一…

蚂蚁KAG框架核心功能研读

首篇KAG框架解读,看蚂蚁KAG框架如何通过知识图谱和向量检索结合,增强大模型在专业领域知识服务中的准确性和逻辑推理能力,解决现有RAG技术栈的挑战。作者介绍:薛明:拥有近10年在医疗和零售领域应用机器学习和人工智能的经验。曾就职于通用电气、复星医药等企业。长期专注于…

Burpsuite下载安装超详细教程,社区版永久有效,专业版汉化激活到2099年,不看会后悔系列,亲测好用!

声明:该公众号大部分文章来自作者日常学习笔记,也有部分文章是经过作者授权和其他公众号白名单转载. 未经授权,严禁转载,如需转,联系开白, 请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关.现在只对常读和星标的公众号才展示大图推送…

非对称加密:猫咪的双钥匙保护 (^• ω •^)

非对称加密:猫咪的双钥匙保护 (^• ω •^) 在之前的博客中,我们讨论了对称加密算法。这种算法使用单一密钥对数据进行加密和解密,但这也带来了一些问题,例如密钥分发和共享的安全风险。为了解决这些问题,非对称加密(Asymmetric Encryption)应运而生。 非对称加密采用…

2024.10.28(商品品牌的增删改查)

按着ALt按左键整体编辑查询功能

【shell脚本】将Shell脚本转换为Systemd服务:轻松实现自动化管理

原创 青菜浪人背景介绍 从 Ubuntu 17.10 开始,/etc/rc.local 文件不再默认存在于系统中,因为 systemd 已成为主要的初始化系统。如果需要在系统启动时自动执行某些命令,可以通过编写 Shell 脚本并将其封装为一个 systemd 服务来实现这一操作。 实现方法 这里以一个简单的脚本…

学期2024-2025-1 学号20241424 《计算机基础与程序设计》第7周学习总结

学期2024-2025-1 学号20241424 《计算机基础与程序设计》第7周学习总结 作业信息 |这个作业属于2024-2025-1-计算机基础与程序设计)| |-- |-- | |这个作业要求在哪里|https://www.cnblogs.com/rocedu/p/9577842.html#WEEK01| |这个作业的目标|参考上面的学习总结模板,把学习过…

鸿蒙开发案例:直尺

【1】引言(完整代码在最后面) 本文将通过一个具体的案例——创建一个横屏显示的直尺应用,来引导读者了解鸿蒙应用开发的基本流程和技术要点。 【2】环境准备 电脑系统:windows 10 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806 工程版本:API 12 真机:Mat…

2024-三叶草安全技术小组第十五届极客大挑战 wp

Crypto 1.凯撒加密 YEI{CKRIUSK_ZU_2024_MKKQ_INGRRKTMK} 6位 SYC{WELCOME_TO_2024_GEEK_CHALLENGE} 2.RSA 原文: from Crypto.Util.number import bytes_to_long, getPrime from secret import flag p = getPrime(128) q = getPrime(128) n = p*q e = 65537 m = bytes_to_lon…

GPT 1-3 简单介绍

GPT-1 简介 2018年6月,OpenAI公司发表了论文"Improving Language Understanding by Generative Pretraining"(用生成式预训练提高模型的语言理解能力), 推出了具有 1.17亿个参数的GPT-1(Generative Pre-training,生成式预训练)模型。 GPT-1 采用 传统的语言模型方…

基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现八

三、系统部分功能描述公告信息业务逻辑层Service、快递取出记录信息业务逻辑层Service、预约物品取出信息业务逻辑层Service、短信发送信息业务逻辑层Service、关于我们控制器Controller、后台用户信息控制器Controller、 快递员信息控制器Controller、物品类型控制器Controlle…

转存——Quartus II FPGA程序仿真运行时出现错误“error occurred during modelsim simulation”的解决方法

起因 使用Quartus II软件进行FPGA程序仿真,运行时出现错误“error occurred during modelsim simulation”,上网查询解决方法,找了很久都没找到,最后在一个CSDN博客的评论里找到解决方法。 现将解决方法转存如下。 错误示例解决步骤 1.依次点击simulation,option2.依次点击…