Ntdll.dll伪代码解读

November 20, 2025 · 0 words

Hyper V_architecture

November 18, 2025 · 0 words

Automatic_answer_Tampermonkey_script

All comments indicating // need modify need to be changed. hint: You can use LLM to get answer and then use this script to answer questions automaticly.>_< json format example : [ { "title": "this is question A", "answer": "false" }, { "title": "this is question B", "answer": "A" } ] // ==UserScript== // @name Automatic_answer_Tampermonkey_script // @namespace http://tampermonkey.net/ // @version 0.1 // @description read JSON file,Automatic_answer // @author you // @match https://example.com/* // need modify // @grant none // ==/UserScript== (function() { 'use strict'; function addControlPanel() { const panel = document.createElement('div'); panel.style.position = 'fixed'; panel.style.top = '10px'; panel.style.right = '10px'; panel.style.zIndex = '999999'; panel.style.background = 'rgba(0,0,0,0.7)'; panel.style.color = '#fff'; panel.style.padding = '10px'; panel.style.borderRadius = '6px'; panel.style.fontSize = '12px'; const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = 'application/json'; fileInput.style.marginBottom = '5px'; fileInput.style.display = 'block'; const btn = document.createElement('button'); btn.textContent = 'Automatic answer'; btn.style.display = 'block'; btn.style.width = '100%'; btn.style.cursor = 'pointer'; panel.appendChild(fileInput); panel.appendChild(btn); document.body.appendChild(panel); let qaList = null; // Read JSON fileInput.addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function() { try { qaList = JSON.parse(reader.result); alert('The answer JSON was loaded successfully, totaling ' + qaList.length + ' questions.'); } catch (err) { console.error(err); alert('JSON parsing failed. Please check if the format is [ {"title":..., "answer":...}, ... '); } }; reader.readAsText(file, 'utf-8'); }); // Click on [Auto Answer] btn.addEventListener('click', function() { if (!qaList) { alert('Please select a JSON file first!'); return; } autoAnswer(qaList); }); } function autoAnswer(qaList) { const questionNodes = document.querySelectorAll('.m-item'); let matchedCount = 0; qaList.forEach(item => { const titleKeyword = String(item.title || '').trim(); const answerKeyword = String(item.answer || '').trim(); if (!titleKeyword || !answerKeyword) return; questionNodes.forEach(qNode => { // The question stem is in .subject-title.examTitle const titleNode = qNode.querySelector('.subject-title.examTitle'); // need modify if (!titleNode) return; const titleText = titleNode.innerText.trim(); // Use "contains" to match questions (not requiring exact consistency, so you can fill in only a part). if (!titleText.includes(titleKeyword)) return; // Options: under .select-box, label .ivu-radio-wrapper const optionLabels = qNode.querySelectorAll('.select-box .ivu-radio-wrapper'); // need modify let clicked = false; optionLabels.forEach(label => { if (clicked) return; const optionText = label.innerText.trim(); const input = label.querySelector('input.ivu-radio-input'); // need modify if (!input) return; // Matching method: // 1. Option text contains answer keywords (e.g., "True" or "False") // 2. Compatible with A./A format if ( optionText.includes(answerKeyword) || // Content contains optionText.startsWith(answerKeyword + '.') || // A. xxx optionText.startsWith(answerKeyword + '、') || // A、xxx optionText.startsWith(answerKeyword + ' ') // A xxx ) { // Prioritize input fields for compatibility with some framework events input.click(); // Click the label again for backup label.click(); clicked = true; matchedCount++; console.log('The title [' + titleKeyword + '] has been selected:' + optionText); } }); }); }); alert('The system will automatically click "Complete," successfully matching and selecting approximately '+ matchedCount+' options.'); } window.addEventListener('load', function() { // Sometimes the questions are rendered asynchronously, so you can wait a little while. setTimeout(addControlPanel, 1500); }); })();

November 18, 2025

Windows heap learning

Windows Heap Internals learning windows heap is divided into two types:NT heap and segment heap NT heap Exists since early versions of Windows NT. The default heap implementation up through Windows 7/8. Segment heap (why not public) Introduced in Windows 10 as the modern heap manager. Default for apps built with the Universal Windows Platform (UWP), Microsoft Edge, and newer apps. Heap structure A heap consist of some segments.Each segment has a continuous space. A segment consist of some Entry Here is the structure of heap: ...

October 22, 2025 · 1988 words

Windows内存管理学习

一. 关于内存管理 1.1 虚拟地址空间 每个进程的虚拟地址是私有的并且无法被其他进程访问(除非共享)。系统为每个进程维护一个页表用来将虚拟地址变为物理地址。 虚拟地址空间的大小受到不同的cpu架构,不同的windows操作系统和LargeAddressAware与 4GT 设置影响。 1.1.1 32位 ——4GT设置 在 32 位系统中,虚拟地址是 4 GB(2³² = 4 GB): 默认情况:用户程序最多只能访问 2 GB 的虚拟地址 启用 4GT 后分布变成: 这样用户态程序能用更多虚拟内存(适合数据库、游戏服务器等),但内核空间只有 1 GB,系统缓存和驱动可用空间变少。 启用方式 Windows Vista 及更高版本:bcdedit /set increaseuserva <值> Windows Server 2003 及更早:在 Boot.ini 中添加: /3GB 或者更细调 /USERVA=2560 让程序识别 4GT —— /LARGEADDRESSAWARE 编译时加: link /LARGEADDRESSAWARE myapp.obj 没加此标志 → 即使系统启用了 4GT,程序仍只能看到 2 GB。 加了 → 在 /3GB 系统上可看到 3 GB,在 64 位系统上甚至可用 4 GB。 ...

October 14, 2025 · 1495 words

Linux堆学习

前言 要深入了解linux的内存管理,对于堆栈的认识是必不可少的。相对于栈来说,堆相对来说更加复杂。所以在看了大量文章以后,决定对堆中的一些基本概念总结一下,希望师傅们指教。 本文只讨论单线程,64位,glibc2.41版本 (等后续有空更新 堆的定义 ctf-wiki中是这样描述的 在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。 堆其实就是程序虚拟地址空间的一块连续的线性区域,它由低地址向高地址方向增长。 我们一般称管理堆的那部分程序为堆管理器。 堆主要有两个作用: 响应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序。 管理用户所释放的内存 malloc 流程图 free流程图 堆的利用 这个版本的glibc在向上合并的时候并没有把当前块的控制信息消除,所以可以double-free #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h> #define te int main() { int i = 0; void *x[7]; for(i; i<7;i++){ x[i] = malloc(0x100); } void *p1; p1 = malloc(0x200); void *p2; p2 = malloc(0x200); malloc(10); // 防止和av->top 合并 for(i = 0; i< 7 ;i++){ free(x[i]); } // 填满tcache_bins free(p1); // 放入small_bins free(p2); // 触发合并刚好进入unsorted_bins,并且没有清空控制信息 malloc(0x200); free(p2); // double-free getchar(); return 0; }

September 26, 2025 · 80 words

OLED 使用自建文字库显示中文

Arduino的很多设备都无法显示中文,一般是使用图形显示中文内容。同样,也可以用u8g2显示中文。但是自带的中文字库并不能很好的满足我们的需求,极有可能会出现中文无法显示的情况,所以我们需要自建库。 首先去GitHub上下载u8g2的代码,把tools文件夹复制到Arduino下载的u8g2库文件目录下。 进入到U8g2/tools/font/build,找到chinese1.map。把要的中文字转为Unicode写入,注意格式和逗号。 text = "当前时间:" text = text.encode("unicode_escape").replace(b"\\u", b"$").decode("utf-8") formatted_text = ",\n".join([text[i:i+5] for i in range(0, len(text), 5)]) print(formatted_text) 接着回到U8g2/tools/font/bdfconv,打开命令行输入 bdfconv.exe -v ../bdf/unifont.bdf -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_unifont -o u8g2_font_unifont.c 完成转码后,字库代码会在u8g2_font_unifont.c中,打开后把内容复制一下。 数组长度别忘了,这个也一定要复制。然后U8g2/src/clib/u8g2_fonts.c,找到u8g2_font_unifont_t_chinese1,把刚刚所说的复制进去。 最后我们点亮就可以看到显示中文啦。 #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <ESP8266WiFi.h> #include <NTPClient.h> #include <U8g2lib.h> #include <WiFiUdp.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); const char* ssid = "Xiaomi13"; const char* password = "1234567878"; WiFiUDP udp; NTPClient timeClient(udp, "pool.ntp.org", 0, 60000); void setup() { Serial.begin(9600); u8g2.enableUTF8Print(); //开启utf-8文字显示 WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); timeClient.begin(); timeClient.setTimeOffset(3600*8); u8g2.begin(); u8g2.clearBuffer(); } void loop() { timeClient.update(); String currentTime = timeClient.getFormattedTime(); u8g2.clearBuffer(); do{ u8g2.setFont(u8g2_font_unifont_t_chinese1); u8g2.setCursor(0, 15); u8g2.print("当前时间:"); u8g2.setFont(u8g2_font_6x12_tr); u8g2.setCursor(0,30); u8g2.print(currentTime.c_str()); }while(u8g2.nextPage()); u8g2.sendBuffer(); delay(1000); } 大功告成!

February 6, 2025 · 130 words

My First Post

这是我的第一篇博客,使用 Hugo 搭建!

February 4, 2025