一 加密函数

1. base64加密函数

(1)buuctf 刮开有奖1(未转换)

_BYTE *__cdecl sub_401000(int a1, int a2)
{
  int v2; // eax
  int v3; // esi
  size_t v4; // ebx
  _BYTE *v5; // eax
  _BYTE *v6; // edi
  int v7; // eax
  _BYTE *v8; // ebx
  int v9; // edi
  int v10; // edx
  int v11; // edi
  int v12; // eax
  int i; // esi
  _BYTE *result; // eax
  _BYTE *v15; // [esp+Ch] [ebp-10h]
  _BYTE *v16; // [esp+10h] [ebp-Ch]
  int v17; // [esp+14h] [ebp-8h]
  int v18; // [esp+18h] [ebp-4h]

  v2 = a2 / 3;
  v3 = 0;
  if ( a2 % 3 > 0 )
    ++v2;
  v4 = 4 * v2 + 1;
  v5 = malloc(v4);
  v6 = v5;
  v15 = v5;
  if ( !v5 )
    exit(0);
  memset(v5, 0, v4);
  v7 = a2;
  v8 = v6;
  v16 = v6;
  if ( a2 > 0 )
  {
    while ( 1 )
    {
      v9 = 0;
      v10 = 0;
      v18 = 0;
      do
      {
        if ( v3 >= v7 )
          break;
        ++v10;
        v9 = *(unsigned __int8 *)(v3 + a1) | (v9 << 8);
        ++v3;
      }
      while ( v10 < 3 );
      v11 = v9 << (8 * (3 - v10));
      v12 = 0;
      v17 = v3;
      for ( i = 18; i > -6; i -= 6 )
      {
        if ( v10 >= v12 )
        {
          *((_BYTE *)&v18 + v12) = (v11 >> i) & 0x3F;
          v8 = v16;
        }
        else
        {
          *((_BYTE *)&v18 + v12) = 64;
        }
        *v8++ = byte_407830[*((char *)&v18 + v12++)];
        v16 = v8;
      }
      v3 = v17;
      if ( v17 >= a2 )
        break;
      v7 = a2;
    }
    v6 = v15;
  }
  result = v6;
  *v8 = 0;
  return result;
}

逆向java exe 逆向工程_安全

二 功能函数

1. 排序函数

(1)buuctf 刮开有奖1(未转换)

v7[0] = 90;
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
int __cdecl sub_4010F0(int a1, int a2, int a3)
{
  int result; // eax
  int i; // esi
  int v5; // ecx
  int v6; // edx

  result = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = 4 * i;
    v6 = *(_DWORD *)(4 * i + a1);
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > *(_DWORD *)(a1 + 4 * result) )
        {
          if ( i >= result )
            break;
          ++i;
          *(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result);
          if ( i >= result )
            break;
          while ( *(_DWORD *)(a1 + 4 * i) <= v6 )
          {
            if ( ++i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = 4 * i;
          *(_DWORD *)(a1 + 4 * result) = *(_DWORD *)(4 * i + a1);
        }
        --result;
      }
      while ( i < result );
    }
LABEL_13:
    *(_DWORD *)(a1 + 4 * result) = v6;
    sub_4010F0(a1, a2, i - 1);
    result = a3;
    ++i;
  }
  return result;
}

2.数学函数

ctfshow - 数学不及格(线性求解斐波拉契数列)返回值为斐波那契数列第n项

__int64 __fastcall f(int a1)
{
  int i; // [rsp+1Ch] [rbp-14h]
  __int64 v3; // [rsp+20h] [rbp-10h]
  _QWORD *ptr; // [rsp+28h] [rbp-8h]

  if ( a1 <= 1 || a1 > 200 )
    return 0LL;
  ptr = malloc(8LL * a1);
  *ptr = 1LL;
  ptr[1] = 1LL;
  v3 = 0LL;
  for ( i = 2; i < a1; ++i )
  {
    ptr[i] = ptr[i - 1] + ptr[i - 2];
    v3 = ptr[i];
  }
  free(ptr);
  return v3;
}

三 各种库函数

C语言

stdlib.h 库 strtol()

描述

C 库函数 *long int strtol(const char *str, char *endptr, int base) 把参数 str 所指向的字符串根据给定的 base 转换为一个长整数(类型为 long int 型),base 必须介于 2 和 36(包含)之间,或者是特殊值 0。

声明

下面是 strtol() 函数的声明。

long int strtol(const char *str, char **endptr, int base)

参数

  • str – 要转换为长整数的字符串。
  • endptr – 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。
  • base – 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。转换数字的进制数。

返回值

该函数返回转换后的长整数,如果没有执行有效的转换,则返回一个零值。

实例

下面的实例演示了 strtol() 函数的用法。

#include <stdio.h>
#include <stdlib.h>

int main()
{
   char str[30] = "2030300 This is test";
   char *ptr;
   long ret;

   ret = strtol(str, &ptr, 10);
   printf("数字(无符号长整数)是 %ld\n", ret);
   printf("字符串部分是 |%s|", ptr);

   return(0);
}

让我们编译并运行上面的程序,这将产生以下结果:

数字(无符号长整数)是 2030300
字符串部分是 | This is test|

stdlib.h 库 atoi()

atoi (表示 ascii to integer)是把字符串转换成整型数的一个函数,应用在计算机程序和办公软件中。int atoi(const char *nptr) 函数会扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0 。 特别注意,该函数要求被转换的字符串是按十进制数理解的。atoi输入的字符串对应数字存在大小限制(与int类型大小有关),若其过大可能报错-1。

#include <stdlib.h>
#include <stdio.h>
 
int main(void)
{
    int n;
    char *str = "12345.67";
    n = atoi(str);
    printf("n=%d\n",n);
    return 0;
}
输出为 n = 12345
#include <stdlib.h>
#include <stdio.h>
 
int main()
{
    char a[] = "-100";
    char b[] = "123";
    int c;
    c = atoi(a) + atoi(b);
    printf("c=%d\n", c);
    return 0;
}
输出为 c = 23

四 PE文件详解

五 加壳与脱壳的原理和实现

六 Windows核心编程

Hello,world

#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	MessageBox(NULL, TEXT("hello,world"), TEXT("title"), MB_OK | MB_ICONWARNING | MB_DEFBUTTON1);
	return 0;
}

字符类型

#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	const TCHAR* szContant = TEXT("hello,world");
	static TCHAR szCaption[] = TEXT("title");
	MessageBox(NULL, szContant, szCaption, MB_OK | MB_ICONWARNING | MB_DEFBUTTON1);
	return 0;
}
	MessageBox(NULL, TEXT("hello,world"), TEXT("title"), MB_OK | MB_ICONWARNING | MB_DEFBUTTON1);
	return 0;
}

窗口定义

Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数)。

在创建应用程序窗口之前,必须调用 RegisterClass 函数来注册窗口类。该函数只需要一个参数,即指向 WNDCLASS 窗口类的指针。因为 WNDCLASS 类包含了窗口所拥有的基本属性。
结构原型:

1. typedef struct tagWNDCLASSW {
2.   UINT     style;
3.   WNDPROC   lpfnWndProc;
4.   int      cbClsExtra;
5.   int      cbWndExtra;
6.   HINSTANCE  hInstance;
7.   HICON    hIcon;
8.   HCURSOR   hCursor;
9.   HBRUSH    hbrBackground;
10.   LPCWSTR   lpszMenuName;
11.   LPCWSTR   lpszClassName;
12. } WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;

成员解析:

成员

含义

style

指定窗口类型,各种“类风格”(详见下方↓)可以使用按位或操作符组合起来

lpfnWndProc

指定窗口过程(必须是回调函数)

cbClsExtra

预留的额外空间,一般为 0

cbWndExtra

预留的额外空间,一般为 0

hInstance

应用程序的实例句柄

hIcon

为所有基于该窗口类的窗口设定一个图标

hCursor

为所有基于该窗口类的窗口设定一个鼠标指针

hbrBackground

指定窗口背景色

lpszMenuName

指定窗口菜单

lpszClassName

指定窗口类名

style 类风格解析

类风格

含义

CS_VREDRAW

移动或者调整窗口的高度(垂直方向)时,重绘整个窗口

CS_HREDRAW

移动或者调整窗口的宽度(水平方向)时,重绘整个窗口

CS_DBLCLKS

当用户光标在窗口内双击时,允许发送双击消息给窗口过程

CS_OWNDC

给予每个窗口实例分配一个唯一的 DC(注意,尽管这样是很方便,但它必须慎重使用,因为每个 DC 大约要占 800 个字节的内存)

CS_CLASSDC

该窗口类的所有窗口实例都共享一个窗口类 DC

CS_PARENTDC

1. 将子窗口的裁剪区域设置到父窗口的 DC 中去,这样子窗口便可以在父窗口上绘制自身。(注意,这是子窗口从系统缓存中获取 DC,而不是使用父窗口的 DC。) 2. 指定该风格可以提高系统性能

CS_NOCLOSE

禁止系统菜单的关闭选项

CS_SAVEBITS

1. 以位图形式保存被该窗口遮挡的屏幕部分,当给窗口移动以后,系统便可以用该保存的位图恢复屏幕移动的相应部分,从而系统不用向被该窗口遮挡的窗口发送 WM_PAINT 消息 2. 该特性对于菜单类型的窗口比较合适,因为它通常是简短的显示一下之后便消失 3. 设置该特性将增加显示该窗口的时间,因为它通常要先分配保存位图的内存

CS_BYTEALIGNCLIENT

在字节边界上(在 x 方向上)定位窗口的用户区域的位置

CS_BYTEALIGNWINDOW

在字节边界上(在 x 方向上)定位窗口的位置

CS_GLOBALCLASS

1. 当调用 CreateWindow 或 CreateWindowEx 函数来创建窗口时允许它的 hInstance 参数和注册窗口类时传递给 RegisterClass 的 hInstance 参数不同 2. 如果不指定该风格,则这两个 hInstance 必须相同

*call的使用

__cdecl

__cdecl 是 C Declaration 的缩写,表示 C 语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

__stdcall

__stdcall 是 Standard Call 的缩写,是 C++ 的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是 this 指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retnX,X 表示参数占用的字节数,CPU 在 ret 之后自动弹出 X 个字节的堆栈空间,称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。

__pascal

__pascal 是 Pascal 语言(Delphi)的函数调用方式,也可以在 C/C++ 中使用,参数压栈顺序与前两者相反。返回时的清栈方式与 __stdcall 相同。

__fastcall

__fastcall 是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。因此 __fastcall 通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器编译的程序规定的寄存器不同,返回方式和 __stdcall 相当。

__thiscall

__thiscall 是为了解决类成员调用中 this 指针传递而规定的。__thiscall 要求把 this 指针放在特定寄存器中,该寄存器由编译器决定。VC 使用 ecx,Borland 的 C++ 编译器使用 eax。返回方式和 __stdcall 相当。

__fastcall 和 __thiscall 涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以 Windows 上的 COM 对象接口都定义为 __stdcall 调用方式。

C 语言中不加说明默认函数为 __cdecl 方式(C中也只能用这种方式),C++ 也一样,但是默认的调用方式可以在 IDE 环境中设置。

例子:test1(par1, par2, par3);

逆向java exe 逆向工程_系统安全_02

*大写标识符的含义

在 Winodows 的定义中包含着许多大写标识符,这些标识符有很多都是以两个或三个字母作为前缀,且其后紧跟一个下划线:

CS_HREDRAW DT_VCENTER SND_FILENAME
CS_VREDRAW IDC_ARROW WM_CREATE
CW_USEDEFAULT IDI_APPLICATION WM_DESTROY
DT_CENTER MB_ICONERROR WM_PAINT
DT_SINGLELINE SND_ASYNC WS_OVERLAPPEDWINDOW

这些标识符其实都是宏定义,前缀标明该常量所属的一般类别,含义如下表:

前缀

含义

CS

类风格选项(ClassStyle)

CW

创建窗口选项(CreateWindow)

DT

文本绘制选项(DrawText)

IDI

图标的 ID 号(IDIcon)

IDC

光标的 ID 号(IDCursor)

MB

消息框选项(MessageBox)

SND

声音选项(Sound)

WM

窗口消息(WindowsMessage)

WS

窗口风格(WindowStyles)