1.如何利用低代码做好系统整合,实现企业统一管理?
2.alter table move å alter table shrink spaceçåºå«
3.什么是C语言缓冲区溢出漏洞?怎么利用?谁可以提供详细的资料
4.通过do_execve源码分析程序的执行(上)(基于linux0.11)
如何利用低代码做好系统整合,实现企业统一管理?
系统整合对企业的意义在于实现企业信息系统整合,对企业的发展具有重要意义。整合后的系统便于管理、方便使用、身份证ocr 源码利于决策,统一管理平台作为基础支撑,支撑访问策略与资源管理,提供企业信息与资源桥梁,使企业快速获取关注信息。统一经营分析数据中心整合现有数据,确保主数据准确性、完整性和一致性,方便企业使用。构建信息采集交换平台,打通系统间信息壁垒,通过一体化经营分析数据中心,实现数据分析决策所需数据的统一展示。
低代码平台如何做好系统整合?以天翎低代码开发平台为例,提供丰富整合列表,支持多种接口协议和硬件接口调用方式,封装及对接多种软件或硬件接口,提供源代码支持,确保企业无后顾之忧。强大的EIP能力集成异构数据,形成新的数据视图,避免信息孤岛。独特的IoT架构图支持各类装置与技术接入,通过智能AI进行数字化管理。灵活的跳棋棋盘绘制源码API接口支持接口调用、监控,方便整合第三方系统接口。天翎平台可部署在私有服务器中,实现数据管理自主性,提供多种部署方案,确保系统操作响应时间在0.5-3S以内,同时支持一端配置多端同步生产,方便移动办公。
案例展示:天翎低代码平台为中建四局构建的供应链管理系统。中建四局为提升易货贸易工作效率,通过天翎MyApps低代码平台构建全新供应链管理3.0系统,包括供应商管理、合同管理、发货管理、财务计划管理、移动办公等功能。整合后的系统实现供应链管理全面化,提升工作效率,体现系统整合的价值。
alter table move å alter table shrink spaceçåºå«
注æã该åæ æ令并æªæ§è¡æå±å¹æ示çªå£åå»ç¡®å®ä¿ä½¿eipæ令æé继ç»é¡ºåºæ§è¡
ï¼2ï¼æºä»£ç 第è¡è°ç¨æ令invokeExitProcess
æF7é®åæ æ令æ§è¡è°ç¨åæ°å ¥æ ï¼push0åæF7é®æ§è¡æ±ç¼æ令ï¼call<JMP.&kernel.ExitProcess>æéæ¥å ¥æä½æ§è¡è¯¥è°ç¨
ç±äºè¯¥å¤è¿è·³è½¬æ令ææF7é®eipå®ä½æ¡æ令ï¼
E.-FFJMPDWORDPTRDS:[<&kernel.ExitProcess>]
什么是C语言缓冲区溢出漏洞?怎么利用?谁可以提供详细的资料
缓冲区溢出漏洞入门介绍
文/hokersome
一、引言
不管你是否相信,几十年来,缓冲区溢出一直引起许多严重的安全性问题。甚至毫不夸张的说,当前网络种种安全问题至少有%源自缓冲区溢出的问题。远的不说,一个冲击波病毒已经令人谈溢出色变了。而作为一名黑客,了解缓冲区溢出漏洞则是一门必修课。网上关于溢出的懒人导航源码0漏洞的文章有很多,但是大多太深或者集中在一个主题,不适合初学者做一般性了解。为此,我写了这篇文章,主要是针对初学者,对缓冲区溢出漏洞进行一般性的介绍。
缓冲区溢出漏洞是之所以这么多,是在于它的产生是如此的简单。只要C/C++程序员稍微放松警惕,他的代码里面可能就出现了一个缓冲区溢出漏洞,甚至即使经过仔细检查的代码,也会存在缓冲区溢出漏洞。
二、溢出
听我说了这些废话,你一定很想知道究竟什么缓冲区溢出漏洞,溢出究竟是怎么发生的。好,现在我们来先弄清楚什么是溢出。以下的我将假设你对C语言编程有一点了解,一点点就够了,当然,越多越好。
尽管缓冲区溢出也会发生在非C/C++语言上,但考虑到各种语言的运用程度,我们可以在某种程度上说,缓冲区溢出是C/C++的专利。相信我,如果你在一个用VB写的程序里面找溢出漏洞,你将会很出名。回到说C/C++,源码sip缩写含义在这两种使用非常广泛的语言里面,并没有边界来检查数组和指针的引用,这样做的目的是为了提高效率,而不幸的是,这也留下了严重的安全问题。先看下面一段简单的代码:
#include<stdio.h>
void main()
{
char buf[8];
gets(buf);
}
程序运行的时候,如果你输入“Hello”,或者“Kitty”,那么一切正常,但是如果输入“Today is a good day”,那么我得通知你,程序发生溢出了。很显然,buf这个数组只申请到8个字节的内存空间,而输入的字符却超过了这个数目,于是,多余的字符将会占领程序中不属于自己的内存。因为C/C++语言并不检查边界,于是,程序将看似正常继续运行。如果被溢出部分占领的内存并不重要,或者是一块没有使用的内存,那么,程序将会继续看似正常的运行到结束。但是,如果溢出部分占领的正好的是存放了程序重要数据的内存,那么一切将会不堪设想。
实际上,缓冲区溢出通常有两种,堆溢出和堆栈溢出。敏感信息脱敏源码尽管两者实质都是一样,但由于利用的方式不同,我将在下面分开介绍。不过在介绍之前,还是来做一些必要的知识预备。
三、知识预备
要理解大多数缓冲区溢出的本质,首先需要理解当程序运行时机器中的内存是如何分配的。在许多系统上,每个进程都有其自己的虚拟地址空间,它们以某种方式映射到实际内存。我们不必关心描述用来将虚拟地址空间映射成基本体系结构的确切机制,而只关心理论上允许寻址大块连续内存的进程。
程序运行时,其内存里面一般都包含这些部分:1)程序参数和程序环境;2)程序堆栈,它通常在程序执行时增长,一般情况下,它向下朝堆增长。3)堆,它也在程序执行时增长,相反,它向上朝堆栈增长;4)BSS 段,它包含未初始化的全局可用的数据(例如,全局变量); 5)数据段,它包含初始化的全局可用的数据(通常是全局变量);6)文本段,它包含只读程序代码。BSS、数据和文本段组成静态内存:在程序运行之前这些段的大小已经固定。程序运行时虽然可以更改个别变量,但不能将数据分配到这些段中。下面以一个简单的例子来说明以上的看起来让人头晕的东西:
#include<stdio.h>
char buf[3]="abc";
int i;
void main()
{
i=1
return;
}
其中,i属于BBS段,而buf属于数据段。两者都属于静态内存,因为他们在程序中虽然可以改变值,但是其分配的内存大小是固定的,如buf的数据大于三个字符,将会覆盖其他数据。
与静态内存形成对比,堆和堆栈是动态的,可以在程序运行的时候改变大小。堆的程序员接口因语言而异。在C语言中,堆是经由 malloc() 和其它相关函数来访问的,而C++中的new运算符则是堆的程序员接口。堆栈则比较特殊,主要是在调用函数时来保存现场,以便函数返回之后能继续运行。
四、堆溢出
堆溢出的思路很简单,覆盖重要的变量以达到自己的目的。而在实际操作的时候,这显得比较困难,尤其是源代码不可见的时候。第一,你必须确定哪个变量是重要的变量;第二,你必须找到一个内存地址比目标变量低的溢出点;第三,在特定目的下,你还必须让在为了覆盖目标变量而在中途覆盖了其他变量之后,程序依然能运行下去。下面以一个源代码看见的程序来举例演示一次简单的堆溢出是如何发生的:
#include "malloc.h"
#include "string.h"
#include "stdio.h"
void main()
{
char *large_str = (char *)malloc(sizeof(char)*);
char *important = (char *)malloc(sizeof(char)*6);
char *str = (char *)malloc(sizeof(char)*4);
strcpy(important,"abcdef");//给important赋初值
//下面两行代码是为了看str和important的地址
printf("%d/n",str);
printf("%d/n",important);
gets(large_str);//输入一个字符串
strcpy(str, large_str);//代码本意是将输入的字符串拷贝到str
printf("%s/n",important);
}
在实际应用中,这样的代码当然是不存在的,这只是一个最简单的实验程序。现在我们的目标是important这个字符串变成"hacker"。str和important的地址在不同的环境中并不是一定的,我这里是和。很好,important的地址比str大,这就为溢出创造了可能。计算一下可以知道,两者中间隔了个字节,因此在输入溢出字符串时候,可以先输入个任意字符,然后再输入hakcer回车,哈哈,出来了,important成了"hacker"。
五、堆栈溢出
堆溢出的一个关键问题是很难找到所谓的重要变量,而堆栈溢出则不存在这个问题,因为它将覆盖一个非常重要的东西----函数的返回地址。在进行函数调用的时候,断点或者说返回地址将保存到堆栈里面,以便函数结束之后继续运行。而堆栈溢出的思路就是在函数里面找到一个溢出点,把堆栈里面的返回地址覆盖,替换成一个自己指定的地方,而在那个地方,我们将把一些精心设计了的攻击代码。由于攻击代码的编写需要一些汇编知识,这里我将不打算涉及。我们这里的目标是写出一个通过覆盖堆栈返回地址而让程序执行到另一个函数的堆栈溢出演示程序。
因为堆栈是往下增加的,因此,先进入堆栈的地址反而要大,这为在函数中找到溢出点提供了可能。试想,而堆栈是往上增加的,我们将永远无法在函数里面找到一个溢出点去覆盖返回地址。还是先从一个最简单的例子开始:
void test(int i)
{
char buf[];
}
void main()
{
test(1);
}
test 函数具有一个局部参数和一个静态分配的缓冲区。为了查看这两个变量所在的内存地址(彼此相对的地址),我们将对代码略作修改:
void test(int i)
{
char buf[];
printf("&i = %d/n", &i);
printf("&buf[0] = %d/n", buf);
}
void main()
{
test(1);
}
需要说明的是,由于个人习惯的原因,我把地址结果输出成进制形式,但愿这并不影响文章的叙述。在我这里,产生下列输出:&i = &buf[0] = 。这里我补充一下,当调用一个函数的时候,首先是参数入栈,然后是返回地址。并且,这些数据都是倒着表示的,因为返回地址是4个字节,所以可以知道,返回地址应该是保存在从到。因为数据是倒着表示的,所以实际上返回地址就是:buf[]***+buf[]**+buf[]*+buf[]。
我们的目标还没有达到,下面我们继续。在上面程序的基础,修改成:
#include <stdio.h>
void main()
{
void test(int i);
test(1);
}
void test(int i)
{
void come();
char buf[];//用于发生溢出的数组
int addr[4];
int k=(int)&i-(int)buf;//计算参数到溢出数组之间的距离
int go=(int)&come;
//由于EIP地址是倒着表示的,所以首先把come()函数的地址分离成字节
addr[0]=(go << )>>;
addr[1]=(go << )>>;
addr[2]=(go << 8)>>;
addr[3]=go>>;
//用come()函数的地址覆盖EIP
for(int j=0;j<4;j++)
{
buf[k-j-1]=addr[3-j];
}
}
void come()
{
printf("Success!");
}
一切搞定!运行之后,"Success!"成功打印出来!不过,由于这个程序破坏了堆栈,所以系统会提示程序遇到问题需要关闭。但这并不要紧,因为至少我们已经迈出了万里长征的第一步。
通过do_execve源码分析程序的执行(上)(基于linux0.)
execve函数是操作系统的关键功能,它允许程序转变为进程。本文通过剖析do_execve源码,揭示程序转变成进程的机制。do_execve被视为系统调用,其运行过程在前文已有详细解析,此处不再赘述。分析将从sys_execve函数开启。
在执行_do_execve前,先审视内核栈。接下来,我们将深入理解do_execve的实现。
在加载可执行文件时,存在两种情况:编译后的二进制文件与脚本文件。脚本文件需加载对应解释器,本文仅探讨编译后的二进制文件。解析流程如下:首先验证文件可执行性和当前进程权限,通过后,仅加载头部数据,具体代码在真正运行时通过缺页中断加载。然后,申请物理内存并存储环境变量和参数,该步骤在copy_string函数中实现。
完成上述步骤后,内核栈结构发生变化。接着,执行代码释放原进程页目录和页表项信息,解除物理地址映射,这些信息通过fork继承。随后,调用change_ldt函数设置代码段、数据段基地址和限长,其中数据段限长为MB,代码段限长根据执行文件头部信息确定。完成物理地址映射后,内存布局随之调整。
紧接着,通过create_tables函数分配执行环境变量和参数的数组。执行完毕后,内存布局进一步调整。最后,设置栈、堆位置,以及eip为执行文件头部指定值,esp为当前栈位置,至此,可执行文件加载阶段完成。下文将探讨执行第一条指令后的后续步骤。