使用CBrother的CLIB库调用windows的API

2.1.0版本CBrother加入了CLib库,最新需要写一个工具,根据路径查杀一个Windows进程,研究了一下,CLib库的用法,感觉还是比较灵活的。

首先我要明确每一个API在系统的哪一个dll里面,我一般都是去微软官网查这个API。(https://docs.microsoft.com/zh-cn/windows/win32/api/),

比如我查OpenProcess这个API,查到如下内容

在Kernel32.dll里面,其他用到的API也都是这样获取信息,下面就可以写代码了。

 import CBCLib.code

 var g_kernel32_init = false;                    //kernel32.dll 是否初始化
var g_kernel32 = null; //Kernel32.dll 句柄
var g_kernel32_OpenProcess = null; //OpenProcess函数
var g_kernel32_CloseHandle = null; //CloseHandle函数
var g_kernel32_GetModuleFileNameExA = null; //GetModuleFileNameExA函数
var g_kernel32_GetLogicalDriveStringsA = null; //GetLogicalDriveStringsA函数
var g_kernel32_QueryDosDeviceA = null; //QueryDosDeviceA函数 var g_psapi_init = false; //psapi.dll 是否初始化
var g_psapi = null; //psapi.dll 句柄
var g_psapi_GetProcessImageFileNameA = null; //GetProcessImageFileNameA函数 const MAX_PATH = 1024; //获取kernel32.dll里面的函数
function initkernel32()
{
if (g_kernel32_init)
{
return;
} g_kernel32_init = true; g_kernel32 = new CLib("kernel32.dll");
if(!g_kernel32.load())
{
print "kernel32.dll load err!";
return;
} //根据函数原型和CLib库类型对应关系写参数列表
g_kernel32_OpenProcess = g_kernel32.findFunc("OpenProcess","pointer","int","bool","int");
g_kernel32_CloseHandle = g_kernel32.findFunc("CloseHandle","bool","int");
g_kernel32_GetModuleFileNameExA = g_kernel32.findFunc("K32GetModuleFileNameExA","int","pointer","pointer","pointer","int");
g_kernel32_GetLogicalDriveStringsA = g_kernel32.findFunc("GetLogicalDriveStringsA","int","int","pointer");
g_kernel32_QueryDosDeviceA = g_kernel32.findFunc("QueryDosDeviceA","int","string","pointer","int");
}

我还用到了psapi.dll里面的函数

 //Psapi.dll里面的函数
function initpsapi()
{
if (g_psapi_init)
{
return;
}
g_psapi_init = true; g_psapi = new CLib("Psapi.dll");
if (!g_psapi.load())
{
print "Psapi.dll load err!";
return;
} //根据函数原型和CLib库类型对应关系写参数列表
g_psapi_GetProcessImageFileNameA = g_psapi.findFunc("GetProcessImageFileNameA","int","pointer","pointer","int");
}

下面是根据进程pid获取进程路径

 const STANDARD_RIGHTS_REQUIRED = 0x000F0000;
const SYNCHRONIZE = 0x00100000;
function GetProcessPath(pid)
{
initkernel32(); //打开目标进程
var hProcess = g_kernel32_OpenProcess.callFunc(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF,false,pid);
if (hProcess.isNull())
{
print "openprocess err! " + pid;
return;
} //构建一个buffer,GetModuleFileNameExA会把路径写进这个buffer里
var pathBuff = new CLibPointer();
pathBuff.malloc(MAX_PATH); var res = g_kernel32_GetModuleFileNameExA.callFunc(hProcess,null,pathBuff,MAX_PATH);
if(res > 0)
{
//GetModuleFileNameExA获取成功
res = pathBuff.readString();
}
else
{
//有些系统获取不成功,需要使用另外一种方法。32位程序获取64位进程也需要用这种方法。
res = GetProcessPathByPsapi(hProcess);
} //释放buffer
pathBuff.free(); //关闭目标进程句柄
g_kernel32_CloseHandle.callFunc(hProcess);
return res;
}

如果GetModuleFileNameExA获取失败了,需要使用GetProcessImageFileNameA获取dos路径,然后转化成绝对路径

 //使用GetProcessImageFileNameA获取进程路径
function GetProcessPathByPsapi(hProcess)
{
initkernel32();
initpsapi(); var newPath = "";
var tempBuff = new CLibPointer();
tempBuff.malloc(MAX_PATH);
var res = g_psapi_GetProcessImageFileNameA.callFunc(hProcess,tempBuff,MAX_PATH);
if(res > 0)
{
var driveStr = new CLibPointer();
driveStr.malloc(MAX_PATH);
//获取所有盘符
if(g_kernel32_GetLogicalDriveStringsA.callFunc(MAX_PATH,driveStr))
{
var dospath = tempBuff.readString();
var driveName = new CLibPointer();
driveName.malloc(MAX_PATH);
var copydriveStr = driveStr.copyAddr(); //遍历盘符,和DOS盘符名称对照
while (1)
{
var szDrive = copydriveStr.readString();
szDrive = strget(szDrive,0,2);
if(g_kernel32_QueryDosDeviceA.callFunc(szDrive,driveName,MAX_PATH))
{
var dname = driveName.readString();
var namelen = strlen(dname);
if(strnicmp(dname,dospath,namelen) == 0)
{
//对上了,说明就是这个路径
newPath = szDrive;
newPath += strget(dospath,namelen);
break;
} //盘符指针向前加4获取下一个盘符
copydriveStr.addAddr(4);
}
else
{
break;
}
} driveName.free();
}
driveStr.free();
} tempBuff.free();
return newPath;
}

下面就是在main函数使用

 var g_path = "E:\\111\\test.exe";       //进程路径
var g_name = "test.exe"; //进程名
function main(params)
{
//这个函数是CBrother提供的,根据进程名获取pid,存到array里
var pidarr = GetProcessByName(g_name);
for (var i = 0; i < pidarr.size() ; i++)
{
//根据pid获取进程路径
var path = GetProcessPath(pidarr[i]);
if (path == g_path)
{
//如果路径匹配上了,杀掉。这个函数也是CBrother提供的,根据进程ID查杀进程
KillProcessByID(pidarr[i]);
}
}
}

用法还是比较容易理解,只要你熟悉windows编程,那么CBrother可以做任意你想做的事情。

上面这个api的用法我已经把代码发给作者了,作者说后续会加入lib库里,后续慢慢扩展成所有的api,这样在windows下使用api的就更方便了。

使用CBrother的CLIB库调用windows的API的更多相关文章

  1. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  2. c运行时库,c标准库,Windows系统api的关系

    原文地址:http://blog.csdn.net/seastars_sh/article/details/8233324 C运行库和C标准库的关系 C标准库,顾名思义既然是标准,就是由标准组织制定的 ...

  3. python 中调用windows系统api操作剪贴版

    # -*- coding: utf-8 -*- ''' Created on 2013-11-26 @author: Chengshaoling ''' import win32clipboard a ...

  4. 善于 调用Windows API

    前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...

  5. (Delphi) Windows 32 API程序设计目录

    这里所有程序均使用Delphi调用Windows 32 API方式实现,并不是使用VCL已经封装好的类实现的! (一)第一个窗口程序 01 创建第一个窗口.

  6. .NET 6学习笔记(4)——如何在.NET 6的Desktop App中使用Windows Runtime API

    Windows Runtime API是当初某软为了区别Win32 API,力挺UWP而创建的另一套Windows 10专用的API集合.后来因为一些原因,UWP没火.为了不埋没很有价值的Window ...

  7. Golang调用windows下的dll动态库中的函数

    Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...

  8. Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件

    Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...

  9. Python调用windows下DLL详解 - ctypes库的使用

    在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分数据的交互.使用python中的ctypes模块可以很方便的调用windows的dll(也包括linux下的so等文件),下面将详 ...

随机推荐

  1. strcpy()、strncpy()和memcpy()对比

    strcpy()函数声明:char *strcpy(char *dest, const char *src)返回参数:指向最终的目标字符串 dest 的指针.注意事项:只能复制char类型的字符数组, ...

  2. Flash安全总结

    ActionScript AS是基于ECMAScript的语言,为了交互的需要flash应用引入ActionScript.ActionScript一共有三个版本,其中3.0较之前两个版本变化很大.Ac ...

  3. 阻塞IO模型

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

  4. 如何在项目中使用Spring异步调用注解@Async

    本文主要介绍如何使用Spring框架提供的异步调用注解@Async,异步线程池配置.异常捕获处理. 开启@Async注解支持 使用@Async注解的之前,必须在项目中启动时调用@EnableAsync ...

  5. 【原】centos上安装newman

    1.安装node/npm 1.Newman(因为Newman是node编写,需要依赖nodejs):可以使用先下载安装包到 /usr/local路径下 /usr/local# wget https:/ ...

  6. SpringBoot中如何灵活的实现接口数据的加解密功能?

    数据是企业的第四张名片,企业级开发中少不了数据的加密传输,所以本文介绍下SpringBoot中接口数据加密.解密的方式. 本文目录 一.加密方案介绍二.实现原理三.实战四.测试五.踩到的坑 一.加密方 ...

  7. .NET Core3.0 日志 logging

    多年的经验,日志记录是软件开发的重要组成部分.没有日志记录机制的系统不是完善的系统.在开发阶段可以通过debug附件进程进行交互调试,可以检测到一些问题,但是在上线之后,日志的记录起到至关重要的作用. ...

  8. java秀发入门到优雅秃头路线导航【教学视频+博客+书籍整理】

    目录 一.Java基础 二.关于JavaWeb基础 三.关于数据库 四.关于ssm框架 五.关于数据结构与算法 六.关于开发工具idea 七.关于项目管理工具Mawen.Git.SVN.Gradle. ...

  9. mysql中if函数的正确使用姿势

    --为了今天要写的内容,运行了将近7个小时的程序,在数据库中存储了1千万条数据.-- 今天要说的是mysql数据库的IF()函数的一个实例. 具体场景如下, 先看看表结构: CREATE TABLE ...

  10. 实战SpringCloud响应式微服务系列教程(第九章)使用Spring WebFlux构建响应式RESTful服务

    本文为实战SpringCloud响应式微服务系列教程第九章,讲解使用Spring WebFlux构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 从本节开始我们 ...