精华内容
下载资源
问答
  • 这个是在网上搜索的,但还是获取不到。那位大神给改一下,好久没写C了int GetRun(){SECURITY_ATTRIBUTES sa;sa.nLength = sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;...

    这个是在网上搜索的,但还是获取不到。

    那位大神给改一下,好久没写C了

    int GetRun()

    {

    SECURITY_ATTRIBUTES sa;

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);

    sa.lpSecurityDescriptor = NULL;

    sa.bInheritHandle = TRUE;

    HANDLE outHandle;

    outHandle = CreateFile(L"aa.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL);

    PROCESS_INFORMATION processInfo;

    STARTUPINFO startUpInfo;

    memset(&startUpInfo, 0, sizeof(STARTUPINFO));

    memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));

    startUpInfo.cb = sizeof(STARTUPINFO);

    startUpInfo.dwFlags = STARTF_USESTDHANDLES;

    startUpInfo.wShowWindow = SW_SHOWNORMAL;

    startUpInfo.hStdOutput = outHandle;

    if (!CreateProcess(L"Coreinfo.exe", NULL, NULL, NULL, FALSE,

    CREATE_NEW_CONSOLE, NULL, NULL,

    &startUpInfo, &processInfo)){

    CloseHandle(outHandle);

    printf("open hello.exe error\n");

    }

    else

    {

    DWORD filesize = 1000;

    char * buffer = (char *)malloc(filesize + 1);

    memset(buffer, 0, filesize + 1);

    DWORD readsize;

    ReadFile(outHandle, buffer, filesize, &readsize, NULL);

    buffer[filesize] = 0;

    printf("1111111 - %s\n", buffer);

    free(buffer);

    WaitForSingleObject(processInfo.hProcess, INFINITE);

    printf("open hello.exe ok\n");

    CloseHandle(outHandle);

    CloseHandle(processInfo.hProcess);

    CloseHandle(processInfo.hThread);

    }

    return 0;

    }

    展开全文
  • 如果想在a.c中定义一个可以在b.c中可以使用的结构体变量,则可以参照一下方法: 首先在a.h中定义结构体和声明结构体变量,如: ...这样,只要在b.c中#include "a.h",就可以在b文件调用和使用结构体变量aaa了 ...

    如果想在a.c中定义一个可以在b.c中可以使用的结构体变量,则可以参照一下方法:

    首先在a.h中定义结构体和声明结构体变量,如:

    typedef struct struct_a
    {
    //结构体内容
    }
    struct_a;
    
    extern struct_a aaa;

    然后在a.c中定义结构体变量,如下:

    #include "a.h"
    
    struct_a aaa;

    这样,只要在b.c中#include "a.h",就可以在b文件中调用和使用结构体变量aaa了

    展开全文
  • 应用程序执行外部代码一般有多种方式,最显然的就是操作系统提供的链接库的方式,链接库是一个个的库文件,在编译时直接链接到应用程序中,或者是一个独立的库文件供应用程序调用。但常常会有例如下面的一些应用场合...

    应用程序执行外部代码一般有多种方式,最显然的就是操作系统提供的链接库的方式,链接库是一个个的库文件,在编译时直接链接到应用程序中,或者是一个独立的库文件供应用程序调用。

    但常常会有例如下面的一些应用场合:

    你想保护程序的核心代码,想把核心代码加密成一个自己定义的文件,然后在程序运行时加载到内存中执行;

    出于保护或者为了定时更新,你希望自己的核心代码每次都是从网络上下载的,并且不希望在用户硬盘上留下任何痕迹(这儿当然还有更好的DCOM之类的技术更加保护);

    你想注入到其它进程的地址空间中执行;等等。

    那么这篇文章或许对你有所帮助。希望大家不要拿来写后门程序之类的那些违背职业操守和损害他人利益的事 ^_^

    计划连载成二篇,第一篇讲基本原理,每二写个实例。

    虚拟地址空间

    虚拟地址空间是现代操作系统一种先进的内存管理机制,它让任何一个进程拥有自已独立的地址空间(32位CPU 4GB,64位CPU 2^64B),理论上进程可以访问所有这个范围(当然操作系统有用户地址空间和内核地址空间的划分)。只有实际使用的虚拟地址空间的数据才会被映射到物理内存或者磁盘文件上。

    虚拟地址空间上可以分配连续的地址段,提交后会对应到物理内存为主的存储设备上,且在存储设备上不需要一定是连续的。这些虚拟地址段可以有几种模式:只读,只写,读写和执行等。

    操作系统在创建进程时,首先会创建进程的一个虚拟地址空间,然后,把可执行程序中的数据段和代码段拷到虚拟内存中从某个位置开始的地址空间里,这个位置在Linux ELF文件和Windows PE文件里有提供,是程序链接程序填入的,例入Windows的exe文件默认入口地址是400000H,在链接时可以修改这个地址,有时候C语言要实现本文的目的功能,修改入口地址是非常重要的一种方式,汇编语言则无所谓。

    语言相关知识

    现在来看地址编排,

    首先看变量:

    对于全局变量,它是在程序编译时,由编译器固定放到某个虚拟地址空间上的,编译好后相当于就是定死位置了,程序中任何访问该变量都是使用的这个位置且程序员不用管,但对于动态插入的代码段,很显然,他很难知道这个变量的虚拟地址。

    对于函数内的局部变量,基本上是保存在堆栈中的,这个是动态的,所以动态插入的代码可以直接访问到。

    对于参数传递的变量,是在堆栈或者寄存器中的,动态插入的代码也可以直接访问。

    从上面可以看出来,动态插入的代码要访问主程序的全局变量,直接访问是不大可行的,但在被调用时,全局变量的地址可以通过参数传进来,就能直接访问到了。

    接下来看函数:

    函数的地址,也是在程序编译时生成的,生成后就定死了,程序中的任何调用,都将会直接转化成调用这个地址。同样的,动态插入的代码也很难直接知道这些函数的地址。当然,反编译原程序去找地址,再写到动态插入代码中是种方法,不过万一原程序有改动,所有的相对地址可能就全变了.

    实际情况

    下面我们来看看实际的情况,这里,我们以X86家族的32位linux和windows目标程序为例.首先,在两个平台下,编译下面的代码:

    #include

    void kernel(void){

    int a=10;

    int i;

    for(i=0;i<10;i++){

    a++;

    }

    printf("%d\n",a);

    return;

    }

    void main(int argc,char* argv[]){

    printf("%x\n",kernel);//输出函数kernel的虚拟地址

    }

    执行的结果如下图所示:

    09bc9f7b646ee05f7bd91f0fb43baa8f.png

    windows执行结果

    8c974dddfba387b9dfa3fc306f25dc86.png

    linux执行结果

    结果输出了kernel函数的虚拟地址,那么,我们把exe反汇编来看,先看windows.

    a1481f195e045854abb95f4dc1993d21.png

    图中可以看出来,windows的编译器,输出的程序虚拟地址不是函数的真实地址,而是一个跳转表中的条目,这儿的指令是一个跳转,跳转后的地址才是真实地址.

    eb8cee45df94146c9536b008d776948e.png

    跳转到00401020H后,这儿才是kernel函数的真正开始.55 (push ebp)一般是一个函数开始的标志.我们看到,windows上的程序,实际预留了48个字节作为临时变量空间,而我们只声明了两个int,实际上只用了8个字节.其中a是[ebp-4],i是[ebp-8].使用函数内部变量是基于堆栈的,不会出现寻址错误.而for循环用的是一个短jmp,jmp是相对于当前地址的,所以也不会出现寻址错误,最后call 004010F0是调用printf,这个地址我们不能确保编译器在每一个应用程序中都使用同样的地址.所以如果这段代码移动到其它进程的任意虚拟地址去执行,其它的都可以正确执行,唯有这个printf可能失败.

    再来看看gcc编译出来的:

    6dc49156a5a5933eaa7ef6cd6b814082.png

    gcc比windows上的编译器要优化得多了,在取得函数地址的时候,直接就是函数的真实地址,没有到一个跳转指令上去.同样的,移到其它进程的任意虚拟地址上执行,除了调用printf有可能出错外,其它也能顺利执行.

    要在以后的其它进程中执行这个代码,需要把这个代码复制出来到一个文件中,所以,在拷贝这段代码出来的时候,需要判断这个需要弄出来的函数地址的第一个字节是不是0x55,如果是,那这个地址就是函数的真实地址,如果是一个long jump(0xe9),那就将后面的4个(32位)或8个(64位)字节读出来计算相对地址(当前地址加上这个值,还要加上指令本身长度5或9),拷贝到什么时候结束呢?拷贝到ret结束,即intel指令0xc3.不过这个可行性不大,除非你知道所有CPU指令的长度及参数的长度。所以最好的办法就是多拷点,只要保证函数全部拷出去即可。

    拷贝出来的内容就可以以文件的形式和网络下载的形式供其它进程加载了,当然你也可以加密文件,在进程中解密.加载进程通过分配可执行的内存页(windows上的VirtualAlloc或Linux上的mmap),将数据放到内存的指定虚拟地址上,通过函数指针的方式调用.

    对于其它的CPU,也是类似的思路.

    本文就讲到这里,下一篇文章将做一个完整的流程示例.

    展开全文
  • C语言extern调用外部函数

    千次阅读 2016-12-22 21:26:16
    > lsxuanzeSort.c common.c> cat common.c#include //公共函数文件//打印long型数组的内容 void print_array_long(long arr[],long length) { long i; for(i = 0;i;i++){ printf("%ld ",arr[i]);

    > ls

    xuanzeSort.c
    common.c


    > cat common.c

    这里写图片描述

    #include<stdio.h>
    //公共函数文件
    
    //打印long型数组的内容
    void print_array_long(long arr[],long length)
    {
        long i;
        for(i = 0;i<length;i++){
            printf("%ld ",arr[i]);
        }
        printf("\n");
    }
    

    > cat xuanzeSort.c

    这里写图片描述

    #include<stdio.h>
    //选择排序
    void selectSort(long *arr,long length){
        int i,j,temp;
        for(i = 0;i<length;i++){
            for(j = i+1;j<length;j++){
                if(arr[i]>arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    
    //外部声明common.c中的print_array_long函数 打印long型数组
    extern void print_array_long(long arr[],long length);
    
    int main()
    {
        long a[5] = {1,5,88,-1,0};
        print_array_long(a,5);
        selectSort(a,5);
        print_array_long(a,5);
    }
    

    > gcc xuanzeSort.c common.c

    这里写图片描述

    展开全文
  • 比如要在b.c想要调用a.c里的变量aa或函数aaa,则需要将a.c里的变量aa和函数aaa设置为外部变量和函数 方法: 在a.h中声明aa变量和aaa函数: extern int aa; extern void aaa(void); 然后在a.c中定义aa变量和aaa...
  • C语言外部调用结构体,变量和数组

    万次阅读 2018-03-18 10:45:56
    【结构体定义与声明】将结构体写在子文件time.c里,并且在time.h声明外部调用,结果如图,只能在time.c文件中使用,不能实现结构体外部调用。 将结构体的声明和调用都用在time.c文件中,会出现以下情况 *而将...
  • C语言外部函数

    2019-07-24 18:23:30
    在需要调用此函数的文件中,用extern对函数声明,表示该函数是在其他文件中定义的外部函数 实战演练:有一个字符串,内有若干个字符串,要求输入一个字符串,程序便将字符串该字符删去。要求用外部函数实现! #...
  • /* *cmd.exe *test.exe "c:/log.log" "c:/log2.log" */ #include int main(int argc, char *argv[]) { FILE *fp; FILE *fp2;.../*文件写入*/ ch=fgetc(fp); } getchar(); fclose(fp); }
  • 使用联合体的时候, 外部调用一直编译出错, 在网上找了一些方法都是错的或者说的不清楚的, 所以在此记录: 1.在XX.h文件中定义联合体名 2.创建变量声明 这里我声明了两个联合体变量:ALiyun_ticks Start_RTC ...
  • 静态库是在编译时,将库编译成可执行程序,运行时不需要外部函数库。没有依赖性。 动态库是在运行时,将库加载到程序中,运行时需要外部函数库。有依赖性。 Window下的静态库和动态库是.lib和.dll文件 Linux下的静态...
  •   在LuaLaTeX编译方式下,虽然可以直接在tex文件中编写Lua代码,但会受到LaTeX的影响,编写中并不是很便利。所以我在实际使用中一般都把Lua代码的主体部分放在LaTeX的外部,这样可以完全按照以往的编程习惯去编写...
  • C语言定义外部全局函数,只需要在定义当前函数的头文件,多加如下声明,就可以在外部文件调用该函数。 #ifdef __cplusplus extern "C"{ #endif int test();//定义全局函数 #ifdef __cplusplus } #endif ...
  • c语言 读写配置文件

    2020-03-02 13:12:00
     读写配置文件可以分成底层API接口和调用API的界面二个模块,二个模块间耦合度要尽量低,底层封装的API要尽量好用。 不要让人家写人家的时候还需要自己去判断配置项是否已经存在,这些功能底层API要做完善。 一 ...
  • C语言学习—文件

    2018-05-19 19:55:48
    文 件①文件的概念:所谓“文件”是指一组...②文件通常是驻留在外部介质(如磁盘)上的,在使用时才调入内存中来。③文件的打开与关闭:(1)文件的打开 fopen()函数。调用形式: 文件指针名=fopen(文件名,打开文...
  • 1、现在 FRAM.h 文件中声明一个结构体 struct FRAM_W_ADDR  {  char end[3];  char start[3];   }; extern struct FRAM_W_ADDR DATA_REC_ADDR;   2、在FARM.c文件中定义一个结构体变量  struct FRAM_W_ADDR...
  • 1: 在C文件中声名函数为外部extern 2: 在C文件里面的参数声名, 会直接保在R0~R3(参数小于5个),其它参数保存在SP指向的栈 3: 在汇编文件里面要声名函数数是可以外部使export ***************************...
  • C语言外部函数与内部函数

    万次阅读 2017-12-18 17:09:11
    函数的调用,一般是对同一个源文件中的其他函数进行调用的,也可以对另外一个源文件中的函数进行调用 C语言中,根据函数能否被其他源文件调用,分为内部函数和外部...调用外部函数之前,需要在当前源文件中定义外部函
  • 起因 做个C小实验,向判断一个动态库对外暴露的接口函数能否同时被两个程序调用,...如果在一个源文件中定义的函数只能被本文件中的函数调用,而不能被同一源程序其它文件中的函数调用, 这种函数称为内部函 数。定义
  • 首先用c语言编写一个简单的计算阶乘的程序,代码如下: #include<stdio.h> int main(int argc,char *argv[]){ //计算n的阶乘 int i=0,j; int sum=0; int base=0; int product=1; char* str=argv[1]; if...
  • C语言外部变量(extern)的使用

    千次阅读 2012-11-08 20:40:34
    C语言外部变量的定义和引用对初学者来说,是个难点.对外部变量的说明和定义不是一回事.对外部变量的说明,只是声明该变量是在...用extern声明外部变量,目的是可以在其它的文件调用.具体使用见下面的例子: file1.c 
  • C语言文件概述

    千次阅读 2016-11-01 21:23:33
    众所周知,数据存储是计算机的主要功能之一,各种数据包括文章,图像,数据库等都以二进制的形式...文件中的数据是需要进行存取和处理的,一般对文件的操作可以通过以下两种方式进行:文件操作命令和文件系统功能调用
  • C语言关于文件概述

    2016-10-12 14:45:13
    众所周知,数据存储是计算机的主要功能之一,各种数据包括文章,图像,数据库等都以二进制的形式...文件中的数据是需要进行存取和处理的,一般对文件的操作可以通过以下两种方式进行:文件操作命令和文件系统功能调用
  • system(); 函数原型:intsystem(constchar*command); ...'abcde'不是内部或外部命令,也不是可运行的程序 ...或批处理文件。...这个很能说明问题:在windows操作系统下,system()函数真正调用的是...
  • Procast调用外部函数

    千次阅读 2020-09-22 14:24:32
    建议安装此版本(帮助文档建议的是vs2013,但是运行时会报错应该是默认库文件是基于vs2010编写的,用vs2013编译时会链接不上)。 1安转vs2010。编写所需的c程序。 2更改bin文件夹里的procastRun_DMP.bat。用记事本...
  • 如何用matlab调用VS15创建的.exe文件(C)Step 1.编写C代码Step 2.matlab调用.exe附录:C中字符串转数据的函数 Step 1.编写C代码 主函数格式:int main(int argc, char *argv[]) 若想从外部向main函数传递参数,该...
  • C语言文件处理

    2013-07-12 16:08:00
    所谓“文件”一般指存储在外部介质上数据的集合。根据数据的组织形式,可分为ASCII文件和二进制文件。ASCII文件,又称为文本文件,它的每一个字节存放一个ASCII代码,代表一个字符。二进制文件是把内存中的数据按其...
  • 内部函数和外部函数内部函数: 需加static声明,又称静态函数,只能在该文件中调用,在其他文件中不能被调用外部函数:1. 在定义函数时,若在函数首部的最左端加关键字extern,则表示此函数是外部函数,可被其他...
  • 本文为大一时所写的文章(2017/4/19),文笔还很生疏,在很多...操作系统是以文件为单位进行管理,希望调用外存文件里的内容就得先去从外部存储中找到文件名输入到缓冲区,从缓冲区再调入到内存中,输出则是个逆过...
  • C语言中一旦程序的功能复杂时,我们便会想到使用多个文件来写函数,即是在...方式2:使用extern 声明外部文件已经定义的函数。这里就先把这两种方式的简单栗子举一个。 (下面的所有代码编辑和编译运行都是使用

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 536
精华内容 214
关键字:

c语言调用外部文件

c语言 订阅