wubba lubba dub dub.
post @ 2022-07-03

Python字符串

  • str 转换bytes

    纯英文的str可以用ASCII编码为bytes,内容是一样的,
    含有中文的str可以用UTF-8编码为bytes
    含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

    bytes中,无法显示为ASCII字符的字节,用\x##显示。

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
  • bytes转换str

    bytes变为str,就需要用decode()方法:

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
  • 计算str包含的字符串/bytes包含的字节数

    1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。

#str包含的字符串
>>> len('ABC')
3
>>> len('中文')
2
#bytes包含的字节数
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6
  • 文件乱码问题

    在操作字符串时,我们经常遇到strbytes的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对strbytes进行转换。

    当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-、

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

阅读此文

前言

网上有一堆 微信电脑版多开、防撤回等破解补丁,可以实现类似的功能,但是微信是比较涉及个人隐私的社交软件,所以网上公开的补丁基本都不敢用,万一自带木马后门什么的就惨了。所以在这里教大家纯手工修改方法。

准备工作

1. OllyDbg 或 OllyICE(OllyDbg 爱好者二次开发升级版本) 等反汇编软件。

2. 安装好微信电脑版,提取安装路径文件夹中的 WeChatWin.dll 备用。

使用 OllyDbg 纯手工修改微信电脑版 WeChatWin.dll 的汇编代码,实现无限多开和消息防撤回功能,并且有撤回提示。

该方法适用于微信电脑版(Windows PC 版)近几年的所有版本,甚至未来新版本。

有一定的技术门槛,需要了解基本的反汇编破解知识,如果不能熟练掌握 OllyDbg 等反汇编软件,那么底下内容就可以不用看了。

破解流程

解除多开限制

阅读此文
post @ 2021-02-08

注册表的打开与关闭

注册表是一个巨大的树形结构。操作一般都是打开某个子键。子键下有若干个值可以获得。每一个值有一个名字。值有不同的类型。一般需要查询才能获得其类型。

应用程序编程:需要提供一个根子键的句柄。

驱动:全部用路径表示。

应用编程中对应的子键 驱动编程中的路径写法:

HKEY_LOCAL_MACHINE \Registry\Machine
HKEY_USERS \Registry\User
HKEY_CLASSES_ROOT 没有对应的路径
HKEY_CURRENT_USER 没有简单的对应路径,但是可以求得

实际上应用程序和驱动程序很大的一个不同在于应用程序总是由某个“当前用户”启动的。因此可以直接读取HKEY_CLASSES_ROOT和HKEY_CURRENT_USER。而驱动程序和用户无关,所以直接去打开HKEY_CURRENT_USER也就不符合逻辑了。

打开注册表键使用函数ZwOpenKey。新建或者打开则使用ZwCreateKey。一般在驱动编程中,使用ZwOpenKey的情况比较多见。

ZwOpenKey 函数

ZwOpenKey 函数(打开注册表键),函数原型如下:

阅读此文
post @ 2021-02-08

句柄的定义

每个进程都有一个表,这个表中的每一项保存着需要访问的内核对象信息,系统为用户态应用程序提供一个“句柄”值,这个句柄值实际上是这个表的某种索引,通过这个值,可以在表中定位到具体需要访问的内核对象信息。用户态程序通过API创建或打开一个内核对象时,这个表中的信息会增加一项,用来描述这个内核对象的信息,并产生一个相应的句柄值,用户态程序把这个句柄传递到相应API,API进入内核后,通过这个句柄值定位到需要操作的内核对象,对内核对象进行相应的操作。

typedef void *HANDLE;
typedef HANDLE *PHANDLE

内核对象的引用计数

每个内核对象存在两个计数,一个称为“句柄计数”,另一个称为“指针计数”,句柄计数是指这个内核对象被多少个句柄值所指向,如在用户态中创建一个命名的EVENT对象,获取到一个句柄,那么这个EVENT的句柄计数就是1,当其他程序通过该EVENT名字打开该EVENT时,会获取到另外一个句柄,这时候,句柄计数等于2。指针计数是在句柄计数基础上递增的计数,在刚才所提的例子中,句柄计数等于2,指针计数也等于2,句柄计数的增加,会相应导致指针计数增加,同理,句柄计数的减少,会相应导致指针计数减少,但指针计数可以独立增加与减少而不影响句柄计数。当一个对象的指针计数等于0的时候,这个对象会被系统释放。请注意,不同操作系统,系统对引用计数值的管理稍有不同。

句柄操作CODE

CODE

#include <stdio.h>
#include <ntddk.h>
#include <ntifs.h>

BOOLEAN EventOperationSample()
{
BOOLEAN bSucc = FALSE;
HANDLE hCreateEvent = NULL;
PVOID pCrateEventObject = NULL;
HANDLE hOpenEvent = NULL;
PVOID pOpenEventObject = NULL;

do
{
OBJECT_ATTRIBUTES ObjAttr = { 0 };
UNICODE_STRING uNameString = { 0 };
RtlInitUnicodeString(&uNameString, L"\\BaseNameObjects\\TestEvent");
InitializeObjectAttributes(&ObjAttr, &uNameString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
ZwCreateEvent(&hCreateEvent, EVENT_ALL_ACCESS, &ObjAttr, SynchronizationEvent, FALSE);
if (hCreateEvent == NULL)
{
break;
}

ObReferenceObjectByHandle(hCreateEvent, EVENT_ALL_ACCESS, *ExEventObjectType, KernelMode, &pCrateEventObject, NULL);
if (hOpenEvent == NULL)
{
break;
}

ObReferenceObjectByHandle(hOpenEvent, EVENT_ALL_ACCESS, *ExEventObjectType, KernelMode, &pCrateEventObject, NULL);

if (pOpenEventObject == NULL)
{
break;
}

DbgPrint("Create Handle: %p, Create Pointer = %p\n", hCreateEvent, pCrateEventObject);
DbgPrint("Open Handle: %p, Open Pointer = %p\n", hOpenEvent, pOpenEventObject);
bSucc = TRUE;
} while (FALSE);
if (pCrateEventObject != NULL)
{
ObDereferenceObject(pCrateEventObject);
pCrateEventObject = NULL;
}

if (hCreateEvent != NULL)
{
ZwClose(hCreateEvent);
hCreateEvent = NULL;
}

if (pOpenEventObject != NULL)
{
ObDereferenceObject(pOpenEventObject);
pOpenEventObject = NULL;
}

if (hOpenEvent != NULL)
{
ZwClose(hOpenEvent);
hOpenEvent = NULL;
}

return bSucc;
}


逻辑分析

ZwCreateEvent成功后,句柄会保存在hCreateEvent变量中,这个句柄是一个内核句柄。接着代码中调用ObReferenceObåjectByHandle函数,获取hCreateEvent句柄对应的EVENT对象指针。

阅读此文
post @ 2021-02-04

原文地址:https://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html

近日在读操作系统导论,看到书中的代码里面有volatile 关键字,找到了一篇不错的文章,所以转载了过来。

为什么用volatile?

C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 “The C++ Programming Language” 对 volatile 修饰词的说明:

A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

例如:

volatile int i=10;
int a = i;
...
// 其他代码,并未明确告诉编译器,对 i 进行过操作
int b = i;

volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。注意,在 VC 6 中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无 volatile 关键字,对程序最终代码的影响,输入下面的代码:

#include <stdio.h>

void main()
{
int i = 10;
int a = i;

printf("i = %d", a);

// 下面汇编语句的作用就是改变内存中 i 的值
// 但是又不让编译器知道
__asm {
mov dword ptr [ebp-4], 20h
}

int b = i;
printf("i = %d", b);
}
阅读此文
post @ 2021-02-03

内存分配与回收

内存分配

ExAllocatePoolWithTag(内存分配函数)

PVOID ExAllocatePoolWithTag(
POOL_TYPE PoolType,
SIZE_T NumberOfBytes,
ULONG Tag
);

PoolType 为 POOL_TYPE 枚举类型,表示需要申请何种类型的内存。

常用的值是 NonPagedPool 与 PagedPool,NonPagedPool表示非分页内存,PagedPool表示分页内存。

注意: 非分页内存是指这块内存的内容不会被置换到磁盘上,非分页内存非常宝贵,一般用于高IRQL(大于等于DISPATCH_LEVEL)的代码中。

两个类型:NonPagedPoolExecute 与 NonPagedPoolNx
NonPagedPoolNx类型是指分配出来的非分页内存不具备“可执行”属性。对非分页内存进行读写而不需要进行代码或指令执行,那么可以使用NonPagedPoolNx类型的内存

NonPagedPoolExecute 类型与 NonPagedPool 类型等价。

NumberOfBytes参数表示需要申请内存大小,单位是字节。

阅读此文
post @ 2021-02-02

自旋锁

自旋锁是内核中提供的一种高IRQL锁,用同步以及独占的方式访问某个资源。

KSPIN_LOCK my_spin_lock;
KeInitializeSpinLock(&my_spin_lock); //函数无返回值

自旋锁的使用方法:

KIRQL irql;		//KIRQL是一个中断级
KeAcquireSpinLock(&my_spin_lock,&irql);
// To do something ...
KeReleaseSpinLock(&my_spin_lock,irql);

KeAcquireSpinLock 和 KeReleaseSpinLock 之间的代码是只有单线程执行的,其他的线程会停留在 KeAcquireSpinLock 等候,直到 KeReleaseSpinLock 被调用。换句话说,只有一个线程能够获得自旋锁。

注意: 锁一般不会定义成局部变量,可以使用静态变量、全局变量,或者分配在池(POOL)中。因为每个线程来执行的时候都会重新初始化一个锁。只有所有的线程共用一个锁,锁才有意义。

/*正确使用自旋锁的例子*/
KSPIN_LOCK my_spin_lock = {0};
Void InitSpinLock()
{
KeInitializeSpinLock(&my_spin_lock);
}
Void MySafeFunction()
{
KIRQL irql;
KeAcquireSpinlock(&my_spin_lock,&irql);
// To do something...
KeRealeaseSpinLock(&my_spin_lock,irql);
}

双向链表自旋锁

在双向链表中使用自旋锁的目的是保证多线程安全。在操作链表之前,调用KeAcquireSpinLock 来获取锁,在操作完成之后,调用 KeReleaseSpinLock 来释放锁。

阅读此文
post @ 2021-02-02

链表的定义:

typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
}LIST_ENTRY, *PLIST_ENTRY;

LIST_ENTRY表示一个链表的节点,其中Flink成员指向当前节点的后一个节点,Blink成员指向当前节点的前一个节点。

链表的使用:

typedef struct _TestListEntry
{
ULONG m_ulDataA;
ULONG m_ulDataB;
LIST_ENTRY m_ListEntry;
/*双向链表节点的结构,m_ListEntry可以放在结构体的任意位置*/
ULONG m_ulDataC;
ULONG m_ulDataD;
}TestListEntry, *PTestListEntry;

m_ulDataA成员处于最低地址,m_ulDataD处于最高地址,而链表节点LIST_ENTRY的两个成员展开后在结构体中分别为Flink与Blink,其中Flink处于低地址,Blink处于高地址。

内存布局

节点的关系

包含头结点

头结点初始化

阅读此文
post @ 2021-02-02

UNICODE_STRING数据类型

内核层编程一般不直接使用WCHAR类型的Unicode字符串,而是使用UNICODE_STRING类型来表示Unicode。

这里简单介绍一下 UNICODE_STRING 类型。

UNICODE_STRING是内核中表示字符串的结构体;

Buffer为一个指针,指向一个UNICODE类型的字符串缓冲区;

MaximumLength表示Buffer所指向缓冲区的总空间大小,一般等于Buffer被分配时的内存大小,单位为字节;

Length表示Buffer所指向缓冲区中字符串的长度,单位也是字节;

注意:Buffer指向的字符串,并不要求以’\0’作为结束,在大多数情况下,Buffer指向的字符串没有以’\0’结尾

typedef struct _UNICODE_STRING{ 
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}UNICODE_STRING, *PUNICODE_STRING;

UNICODE_STRING 初始化

阅读此文
post @ 2021-02-01

《The C++ Programming Language》 第六章函数的一个例子。

没有高深的算法,都是c++中最常用的语法现象,但是这150行程序里蕴含的功力极深(至少我达不到这种水平,程序的效率,存储开销等方面做的都非常出色,甚至是天衣无缝)。

今日贴出,请大家一同欣赏(作者在程序中因为简化程序而改写了一些更好的方法,正如作者在序言中所说,要有一种健康的怀疑态度,我之所以说它完美,并不是指我们编不出比它好的程序,而是指它清晰的结构,合理的设计,以及蕴含在这里面的编程艺术)

////////////////////////////////////////////////////////////// 
//以下是 c++之父写的一个简单计算器程序 包括分析器,输入,符号表,驱动程序
//计算器的输入语法:
// 1)以 ";" 号作为一行的结束
// 2)可用英文单词命名变量 (但变量后要有空格)
// 例子如下:
// 输入: r =2.5; (注意空格)
// 输出: 2.5 (记负值结果)
// 输入: area = r * r * pi ;
// 输出: 19.635
//
// 以下代码为标准c++代码,我在vc++2003.net上运行无误

#include <iostream>
#include <string>
#include <map>
#include <cctype>
using namespace std;
const int ture=1;
const int flase=0;

map<string,double> table;


///////////////////////////////////////////////////////////////
//计算器输入允许的词法
enum Token_value{
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')',
};

///////////////////////////////////////////////////////////////
//分析器 加和减
double expr(bool);

///////////////////////////////////////////////////////////////
//分析器 乘和除
double term(bool);

///////////////////////////////////////////////////////////////
//分析器 处理初等项
double prim(bool);

///////////////////////////////////////////////////////////////
//词法分析器
Token_value get_token();

///////////////////////////////////////////////////////////////
//错误处理
double error(const string &s);

///////////////////////////////////////////////////////////////
//当前词法标记
Token_value curr_tok=PRINT;

double number_value; //存放数值
string string_value; //存放计算器变量名
int no_of_errors; //记录错误个数


double expr(bool get) {
double left=term( get);

for( ; ; )
switch(curr_tok) {
case PLUS:
left+=term(ture);
break;
case MINUS:
left-=term(ture);
break;
default:
return left;
}
}

double term(bool get) {
double left=prim(get);

for( ; ; )
switch(curr_tok) {
case MUL:
left*=prim(ture);
break;
case DIV:
if(double d=prim(ture)) {
left/=d;
break;
}
return error("divide by 0");
default:
return left;
}
}


double prim(bool get) {
if(get) get_token();

switch(curr_tok) {
case NUMBER: {
double v=number_value;
get_token();
return v;
}
case NAME: {
double& v=table[string_value];
if(get_token()==ASSIGN)
v=expr(ture);
return v;
}
case MINUS:
return -prim(ture);
case LP: {
double e=expr(ture);
if(curr_tok!=RP)
return error(") expected");
get_token();
return e;
}
default:
return error("primary expected");
}
}

Token_value get_token() {
char ch=0;
cin>>ch;

switch(ch) {
case 0:
return curr_tok=END;
case ';':
case '*':
case '/':
case '+':
case '(':
case ')':
case '=':
return curr_tok=Token_value(ch);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
cin.putback(ch);
cin>>number_value;
return curr_tok=NUMBER;
default:
if(isalpha(ch)) {
cin.putback(ch);
cin>>string_value;
return curr_tok=NAME;
}
error("bad token");
return curr_tok=PRINT;
}
}

double error(const string& s)
{
no_of_errors++;
cerr<<"error: "<<s<<endl;
return 1;
}

int main()
{
table["pi"]=3.1415926;
table["e"]=2.718281828;

while(cin) {
get_token();
if(curr_tok==END)
break;
if(curr_tok==PRINT)
continue;
cout<<expr(false)<<endl;
}
return no_of_errors;
}

阅读此文
post @ 2020-11-17

常用 Git 命令清单。几个专用名词的译名如下。

Workspace:工作区
Index / Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库

新建代码库

# 在当前目录新建一个Git代码库
$ git init

# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]

配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global]

# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"

增加/删除文件

# 添加指定文件到暂存区
$ git add [file1] [file2] ...

# 添加指定目录到暂存区,包括子目录
$ git add [dir]

# 添加当前目录的所有文件到暂存区
$ git add .

# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p

# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...

# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]

# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]

代码提交

阅读此文
post @ 2020-10-25

反转链表:将链表整体“反过来”,将头变成尾、尾变成头。

反转的链表

反转后的链表

常见的四种方法:

  1. 迭代反转法

  2. 递归反转法

  3. 就地逆置法

  4. 头插法

递归反转法更适用于反转不带头节点的链表;其它 3 种方法既能反转不带头节点的链表,也能反转带头节点的链表。

迭代反转链表

方法:从当前链表的首元节点开始,一直遍历至链表的最后一个节点,这期间会逐个改变所遍历到的节点的指针域,另其指向前一个节点。

具体实现:借助 3 个指针即可。首先我们定义 3 个指针并分别命名为 beg、mid、end。它们的初始指向如下图所示。

阅读此文
post @ 2020-10-25

顺序表

顺序表初始化

定义数据表

  • 顺序表申请的存储容量;

  • 顺序表的长度,也就是表中存储数据元素的个数;

typedef struct Table{
int * head;//声明了一个名为head的长度不确定的数组,也叫“动态数组”
int length;//记录当前顺序表的长度
int size;//记录顺序表分配的存储容量
}table;

注意:head 是我们声明的一个未初始化的动态数组,不要只把它看做是普通的指针。

数据表的初始化

  • 给 head 动态数据申请足够大小的物理空间;

  • 给 size 和 length 赋初值;

#define Size 5 //对Size进行宏定义,表示顺序表申请空间的大小
table initTable(){
table t;
t.head=(int*)malloc(Size*sizeof(int));//构造一个空的顺序表,动态申请存储空间
if (!t.head) //如果申请失败,作出提示并直接退出程序
{
printf("初始化失败");
exit(0);
}
t.length=0;//空表的长度初始化为0
t.size=Size;//空表的初始存储空间为Size
return t;
}

顺序表初始化的过程被封装到了一个函数中,此函数返回值是一个已经初始化完成的顺序表。这样做的好处是增加了代码的可用性,也更加美观。

阅读此文
post @ 2020-10-18

cdecl

cdecl是C语言中使用的调用方式,调用者负责处理栈

#include "stdio.h"

int add(int a,int b)
{
return (a+b)
}

int main(int argc, char *argv[]
{
return add(1,2);
})

在调用完add() 函数之后,使用 ADD ESP,8 命令整理栈。调用者 main() 函数直接清理其压入栈的函数参数,这样的方式叫 cdecl。

cdecl 调用的优点:可以向调用函数传递长度可变的参数,这种长度可变的参数在其他调用中很难实现。

stdcall

stdcll是 win32 API常用的调用方式,被调用者负责清理栈。

#include "stdio.h"

int _stdcall add(int a,int b)
{
return (a+b)
}

int main(int argc, char *argv[]
{
return add(1,2);
})
阅读此文
post @ 2020-10-17

什么是栈帧

栈帧就是利用EBP(栈帧指针,注意不是ESP)寄存器访问栈内局部变量,参数,函数返回地址的手段,在IA-32寄存器中,ESP寄存器承担着栈顶指针的作用,而EBP寄存器则负责行使栈帧指针的职能。

但是在程序运行的过程中,ESP寄存器的值随时发生变化,访问栈中函数的局部变量,参数时候,若以ESP值为基准编写程序会产生困难,并且难使CPU引用到准确的值。所以引入了栈帧。

在调用某些函数时,先要把用作基准点(函数起始地址)的ESP值保存到EBP,并维持在函数内部,这样无论ESP的值如何变化,以EBP的值作为基准(base)就能够安全访问到相关函数的局部变量,参数,返回地址。

分析栈帧

# include "stdio.h"

long add (long a, long b)
{
long x = a ,y = b;
return (x + y);
}

int main(int argc, char* argv[])
{
long a = 1, b = 2;
printf("%d\n", add(a, b));

return 0;
}

main() 函数产生栈帧

int main(int argc, char*argv[])
00401020         55                    push ebp
00401021 8BEC mov ebp,esp
阅读此文
post @ 2020-10-16

基本程序运行寄存器

通用寄存器 (General Purpse Resigisters,32位,8个)

段寄存器 (Segment Register,16位,6个)

程序状态与控制寄存器 (Program Status and Contral Register,32位,1个)

指令指针寄存器(Instruction Pointer, 32位,1个)

  1. 通用寄存器

EAX:(针对操作数和结果数据的) 累加器

EBX:(DS段中的数据指针)基址寄存器

ECX:(字符串和循环操作的)计数器

EDX (I/O指针)数据寄存器

阅读此文

git

post @ 2020-09-27

创建版本库

  1. 选择一个合适的地方,创建一个空目录:
bash
$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit
  1. 通过git init命令把这个目录变成Git可以管理的仓库:
bash
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

在文件夹目录下面会出现一个 .git 的目录,这个目录的作用是Git来跟踪版本管理库的,对于该文件夹下面的文件修改要慎重,盲目修改可能会导致版本库出现问题。
如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。
也不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的。

将文件提交到仓库的步骤

  1. 用命令git add告诉Git,把文件添加到仓库:
bash
$ git add readme.txt

执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。

阅读此文
post @ 2020-08-09

概念

LaTeX是一种基于ΤΕΧ的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在20世纪80年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由TeX所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

MathJax是一个显示网络上数学公式的开源JavaScript引擎库,它可以在所有浏览器上面工作,其中就支持LaTeX,MathML和AsciiMath 符号,里面的数字会被MathJax使用JavaScript引擎解析成HTML,SVG或者是MathML 方程式,然后在现代的浏览器里面显示。 它的设计目标是利用最新的web技术,构建一个支持math的web平台。支持主要的浏览器和操作系统,包括那些移动设备

KaTeX: 可汗学院出品,号称“最快”的数学公式渲染库
支持主流的浏览器:Chrome, Firefox, Safari, Opera和 IE8-IE11。

快速:并发渲染,无需重排页面。根据这个测试,性能绝对秒杀MathJax; +渲染效果好:采用TeX语法,渲染效果达到印刷出版级别; +无依赖:不依赖其它库; +支持服务器端渲染:例如,服务器端的Node.js程序调用KaTeX,把渲染好的HTML片段直接发送给客户端。

在线测试工具

在线测试,我们可以进行latex公式、katex效果一一对应
http://pandao.github.io/editor.md/examples/katex.html
http://latex.codecogs.com/eqneditor/editor.php
http://latex.91maths.com/

latex公式
参考文档:
http://www.mohu.org/info/lshort-cn.pdf

空白
1_1多个连续的空白字符等同为一个空白字符
1_2每行开始的空白字符将被忽略
1_3使用空行来结束段落,两行文本中的空行标志上一段落的结束和
新段落的开始

#空格
使用\quad和\qquad 来表示空格

#特殊字符
前面需要添加\来表示特殊字符
$ % & _ { } # ^ ~

语法对应
\$ \% \& \_ \{ \} \#
\~{} \^{}(测试有问题)

#指数上下标
指数可以用x^a 或者x^{a} 格式来表示,x代表底数,a是指数
下标可以用x_{a}格式来表示,x代表底数,a代表下指数
#下标
a1(a的下标标为1) 表达式:a_{1}

#指数(上标)
x2(x的指数为2) 表达式:x^2

#上下标
b3ij(b的上标为3下标为ij) 表达式:b^{3}_{ij}

#多次上标
ex2(e的上标为x的平方) 表达式:{e^x}^2

#平方根
平方根命令为:\sqrt,n 次方根相应地为: \sqrt[n]

x开根号 表达式:\sqrt{x}
x开三次方根 表达式:\sqrt[3]{x}
对x平方+根号y在开平方:表达式\sqrt{x^{2}+ \sqrt{y}}

#分数
分数使用\frac{a}{b} 排版,a是分子,b是分母
例子如下:
\frac{x^2}{k+1}
x^{\frac{2}{k+1}}
x^{1/2}

#向量
向量由\vec 得到。另两个命令\overrightarrow 和\overleftarrow在定义从A 到B 的向量


#求和运算符
求和运算符由\sum 生成
\sum_{i=1}^{n}

#数学运算符
大于:> 小于:< 小于等于:\le 大于等于:\ge 不等于:\ne 双波浪线:\approx 单波浪线:\sim 子集:\subseteq 属于:\in 不属于:\notin 乘号:\times 除号:\div 加减号:\pm 右双箭头\Rightarrow 右单箭头:\rightarrow 无穷大:\infty 角度斜度\angle


#常用小写希腊字母
\alpha \beta \gamma \sigma \omega \delta \pi \rho \epsilon \eta \lambda \mu \xi \tau \kappa \zeta \phi \chi

e^{2}\neq

#小括号
空格式:\left ( \right )
效果:()
有数据的括号格式:\left ( 123,45 \right )
效果:(123,45)
#中括号
空格式:\left [ \right ]
效果:[]
有数据的括号格式:\left [ 3,5,9 \right ]
效果:[3,5,9]

#尖括号
空数据格式:\left \langle \right \rangle
<>
有数据格式:\left \langle 3,4 \right \rangle
<3,4>


#水平线
使用 \overline 和 \underline 在表达式的上、下方画出水平线
\overline{lindexi.oschina.io}+\underline{lindexi.github.io}

#上大括号
使用\overbrace 和 \underbrace 可以在表达式上方、下方添加花括号

\overbrace{blog.csdn.net/lindexi_gd}_{lindexi} + \underbrace{lindexi.github.io}_{doubi}

#三角函数
\sin\theta
\cos\theta
\tan\theta
\cot \theta

katex前端展示latex数学公式效果

阅读此文
post @ 2020-07-01

0X1 OEP


OEP:(Original Entry Point),程序的入口点,软件加壳就是隐藏了OEP(或者用了假的OEP), 只要我们找到程序真正的OEP,就可以立刻脱壳。

PUSHAD (压栈) 代表程序的入口点

POPAD (出栈) 代表程序的出口点

POPAD与PUSHAD相对应,一般找到这个OEP就在附近啦。

0x2 常见寻找OEP脱壳的方法


方法一:

1.用OD载入,不分析代码!

阅读此文
@echo off
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo System Information >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
systeminfo | findstr /B /C:"OS" > System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Hostname >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
hostname >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Users>> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
net users >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Route table >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
route print >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Netstat INformation>> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
netstat -ano >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Firewall State >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
netsh firewall show state >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Firewall configuration >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
netsh firewall show config >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Scheduled tasks >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
schtasks /query /fo LIST /v >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo tasklist >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
tasklist /SVC >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo net start >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
net start >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo driverquery >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
DRIVERQUERY >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo Wmic hotfix >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
wmic qfe get Caption,Description,HotFixID,InstalledOn >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo reg queries - elavated >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo reg queries - elavated >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
sc qc Spooler >> System_Details.txt
accesschk.exe -ucqv Spooler >> System_Details.txt
accesschk.exe -uwcqv "Authenticated Users" * >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo upnhosts - elavated >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
sc qc upnphost >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
echo End of Script >> System_Details.txt
echo --------------------------------------------------------------------------------------------------- >> System_Details.txt
阅读此文
⬆︎TOP