Hooking a DirectX/COM Interface

Windows运行Switch游戏的技术原理与实操指南 游戏模拟器本质是跨架构的动态二进制翻译与系统调用重定向技术,其核心在于将ARM64指令实时编译为x86-64代码,并劫持原生OS服务(如hid、nvservices)映射至Windows API。Cemu并非传统仿真器,而是依赖JIT编译与Syscall Hooking实现高性能兼容;输入层则需vJoy虚拟HID设备与mouse2joystick精准建模采样率、加速度曲线及语义映射,解决体感延迟与坐标失真问题。该技术路径广泛应用于任天堂游戏PC化、嵌入式逆向及跨平台运行时开发等工程场景。 阅读详情

By Martin Mueller

This article features a description on, how to hook a DirectX/COM Interface. I used the DirectInput interface as an example of how to hook an interface function. 

     Download source files - 45 Kb

Introduction

After all the helpful articles I read here, I am glad that I can contribute a subject which has not yet been covered.

This article features a description on how to hook a DirectX/COM Interface. I used the DirectInput interface as an example of how to hook an interface function.

For the basic windows hook, I refer to an article by Wade Brainerd, which describes the API hooking process

 

Task:

 

To intercept a method of a COM Interface requires an extended approach compared to hooking an API call. If the desired dll is examined, only the create Interface function is actually exported by the dll. So, how can you hook your desired function?

 

 

 

DInput.dll

 

A COM interface is basically a list of virtual function pointers, which are linked together. You merely have to follow the links and modify every node till you finally reach the pointer of the function, which you would like to replace.



Step 1:

As you can see, only the create interface COM functions are visible, so you have to start your hooking chain at the DirectInputCreate function which returns a COM interface.

Here, you have to inject your Dll into the import address table ( IAT) of the calling program.

 

Step 2:

If the calling program invokes a DirectInputCreate, your function is called, you receive a pointer to a pointer of a pointer to a virtual function table, which is the interface of direct input


DECLARE_INTERFACE_(IDirectInputW, IUnknown)
{
    /*** IUnknown methods ***/
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    /*** IDirectInputW methods ***/
    STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE;
    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE;
    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;
};

Step 3:

Now you can create your device with CreateDevice. You will again receive an address to a different virtual function pointer table, which represents the Device.

 

 

 

 

Pick the method you would like to replace and change the virtual function pointer table in the according place to inject your function.

 

Step 4:

Do the actual data manipulation.

  

 

 

Implementation:

 

Step 1:

To hook yourself into an API function, you can simply use the windows API call SetWindowsHookEx. Here you create a system hook to monitor starting processes and match it to your desired program. After you identified your program you have to compare the import module names with the dll you wish to replace. Since this hook is written for direct input, the entry we are looking for is

DINPUT8.DLL. To find this entry you have to loop through the descriptors till you find your dll.

 


// Iterate through each import descriptor, and redirect if appropriate
  while ( pImportDesc->FirstThunk )
  {
    PSTR pszImportModuleName = MakePtr( PSTR, hModEXE, pImportDesc->Name);

    if ( lstrcmpi( pszImportModuleName, Hook->Name ) == 0 )
    {
      sprintf(dbBuffer,"Dll Found in module  %s replace it/n", Hook->Name );
      WriteToLog(dbBuffer);
      RedirectIAT( Hook, pImportDesc, (PVOID)hModEXE );
    }
    
    pImportDesc++;  // Advance to next import descriptor
  }


After you found your entry, you have to remove the write protection from the IAT with


VirtualQuery( pIAT, &mbi, sizeof(mbi) );

to be able to write into the memory. After the memory is open, you have to find your entry by iterate through the IAT.

 


  while ( pIteratingIAT->u1.Function )
  {
    void* HookFn = 0;  // Set to either the SFunctionHook or pStubs.

    if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) )  // import by name
    {
      PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME, pBaseLoadAddr, pINT->u1.AddressOfData );

      // Iterate through the hook functions, searching for this import.
      SFunctionHook* FHook = DLLHook->Functions;
      while ( FHook->Name )
      {
        if ( lstrcmpi( FHook->Name, (char*)pImportName->Name ) == 0 )
        {
          sprintf(dbBuffer,"Hooked function: %s/n",(char*)pImportName->Name );
          WriteToLog(dbBuffer);
          // Save the old function in the SFunctionHook structure and get the new one.
          FHook->OrigFn = (unsigned long*)pIteratingIAT->u1.Function;
          HookFn = FHook->HookFn;
          break;
         }

          FHook++;
        }

      }


Now, you can now replace it with your own one.


  // Replace the IAT function pointer if we have a hook.
  if ( HookFn )
  {
    // Cheez-o hack to see if what we're importing is code or data.
    // If it's code, we shouldn't be able to write to it
    if ( IsBadWritePtr( (PVOID)pIteratingIAT->u1.Function, 1 ) )
    {
      pIteratingIAT->u1.Function = (DWORD)HookFn;
    }
    else if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
    {
      // Special hack for Win9X, which builds stubs for imported
      // functions in system DLLs (Loaded above 2GB).  These stubs are
      // writeable, so we have to explicitly check for this case
      if ( pIteratingIAT->u1.Function > (DWORD)0x80000000 )
          pIteratingIAT->u1.Function = (DWORD)HookFn;
    }
  }

The only thing remaining is to restore the memory attributes, as nothing ever happened.


VirtualProtect( pIAT, sizeof(PVOID) * cFuncs, flOldProtect, &flDontCare);

Step 2:

Inside of the CreateInterface method, we start hooking into the COM interface by injecting our own CreateDevice function pointer into the Virtual function table (Vtbl), which it is returned in the ppvOut pointer of the original call.

 


  DirectInput8Create_Type OldFn = 
      (DirectInput8Create_Type)D3DHook.Functions[D3DFN_DirectInput8Create].OrigFn;
    HRESULT hr = OldFn( hinst, dwVersion, riidltf, ppvOut, punkOuter );

Resolve the pointer until you get the pointer to the Vtbl of the interface.

 

With this address, you have to again remove the memory protection before you can inject your function into the table and save the old function pointer for later use.

Inject your function pointer into the offset of the CreateDevice function pointer inside of the interface Vtbl and restore the memory protection.

 

As you can see, the CreateDevice is the 4th method of the DirectInput interface, which means the offset inside of the Vtbl is 0x0C (pointer(DWORD)*index 3).


typedef struct IDirectInput *LPDIRECTINPUT;

#if !defined(__cplusplus) || defined(CINTERFACE)
#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDirectInput_Release(p) (p)->lpVtbl->Release(p)
#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
#else
#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
#define IDirectInput_AddRef(p) (p)->AddRef()
#define IDirectInput_Release(p) (p)->Release()
#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b)
#endif


After we know where to inject it, we can start thinking about the implementation. When you look at the declaration of CreateDevice in the dinput.h, it does not match up with the declaration you see in the DirectX Help.


HRESULT CreateDevice(      

    REFGUID rguid,
    LPDIRECTINPUTDEVICE *lplpDirectInputDevice,
    LPUNKNOWN pUnkOuter
);


As you can see in the definition inside the dinput.h, you have to add a 4th parameter, which is the interface pointer. This ends up in the following function declaration.


HRESULT __stdcall   PASCAL MyCreateDevice(LPVOID *ppvOut,REFGUID rguid,
    LPDIRECTINPUTDEVICE *lplpDirectInputDevice,
    LPUNKNOWN pUnkOuter

This is important. You have to make sure, to use the __stdcall calling convention in your declaration, since if you refer to the MSDN.

 

The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack. __cdecl is the default calling convention for C and C++ programs. The stack has to be cleaned up by the caller, which is not the case with our function.

When you look at the disassembly of this call, you can see the stack pointer verification function _RTC_CheckEsp is called after the call to the interface function.


if (lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey, NULL)!=DI_OK)
00401365  mov         esi,esp 
00401367  push        0    
00401369  push        offset lpdikey (4552C8h) 
0040136E  push        offset _GUID_SysKeyboard (44643Ch) 
00401373  mov         eax,dword ptr [lpdi (4552C4h)] 
00401378  mov         ecx,dword ptr [eax] 
0040137A  mov         edx,dword ptr [lpdi (4552C4h)] 
00401380  push        edx  
00401381  mov         eax,dword ptr [ecx+0Ch] 
00401384  call        eax  
00401386  cmp         esi,esp 
00401388  call        _RTC_CheckEsp (4026A0h) 
0040138D  test        eax,eax 
0040138F  je          Game_Init+78h (401398h) 
   return(0);
00401391  xor         eax,eax 
00401393  jmp         Game_Init+107h (401427h) 

// set cooperation level
if (lpdikey->SetCooperativeLevel(main_window_handle,

If you forget to declare your function with __stdcall your function will process fine, but you will fail the esp pointer test of this function which sets the eax and test it after the function call.

 

Step 3:

When you now create the device, the call is re-routed to your CreateDevice function.

After you call the original function, you receive a new pointer in lplpDirectInputDevice,

which will direct you to the Vtbl of the device.

 

HRESULT hr = OldCreateDev(ppvOut,rguid,lplpDirectInputDevice,pUnkOuter);

In my sample, I replaced the GetDeviceState, since I can add additional input in the return data of the calling function. To get to the offset, you have to look at the definition inside the DInput.dll. You see that the GetDeviceState function is the 10th method inside of the Device, which leads to an offset of 0x24.

After you know the offset, we can proceed with the instructions in step 2 to remove the protection, store the old pointer, inject your own function, and restore the memory protection.

 

Step 4:

When the GetDeviceState function is called by the target program, the injected function is called and you can manipulate the data as you wish.

About Martin Mueller

DirectInput使用例程 一个使用dxsdk下的DirectInput实例,vc6.0+dxsdk8.0编译通过,欢迎大家下载学习交流! 立即下载

相关推荐

DXInput来做的键盘HOOK的软件源码

DXInput来做的键盘HOOKVB很实用的源码,精心挑选的精品源码

Hook DirectInput->CreateDevice->GetDeviceData解决方案

已解决,来人散分了,Hook DirectInput->CreateDevice->GetDeviceData 在一款使用DirectInput的3D游戏里面,通过Hook DirectInput8Create函数,CreateDevice方法,取得了GetDeviceData函数指针,在GetDeviceData里面已经可以取得键盘输入的数据(程序未使用GetDeviceSta...

xuq09的专栏 3228

国外大牛写的HOOK

国外大牛写的HOOK技术的程序,可以完成HOOK功能

对DirectX/COM接口的挂钩

 对DirectX/COM接口的挂钩           一般的挂钩(Hook)都是针对Windows API或消息的,而本文要讲的是如何挂钩一个DirectX/COM接口,有意思吧,请往下看,文中以DirectInput作为范例进行讲解。           目标         相比挂钩一个API调用,拦截一个COM接口的方法需要做更多的工作,如果我们要拦截的D

谢启东的专栏 7919

DirectInput & Xinput - 遊戲手把控制器範例

DirectInput & Xinput - 遊戲手把控制器範例

使用DirectInput来控制游戏代码

我自己做了一个程序,将它和我以前使用windows消息机制的程序作对比,发现使用DirectInput果然好用。它可以连贯、流畅地响应按键,而使用windows消息的话则没有那么连贯。举个例子吧,我在以前的程序中,按着一个键不放,精灵图形先走一步,顿一下,再进行连贯的行走;而使用DirectInput可以没有停顿地进行行走,更好的是它支持组合按键同时响应。我试了下,按紧上和左,精灵图片就往左上走,这多么的方便啊! 以下把我的程序贴出来。想要整个工程的话,可以下载。因为它还包含了背景图片、精灵图片、动态鼠标指针等其它东西。

Direct3DHook 源码深度剖析2:GetVTblAddresses 如何定位 COM 接口函数指针

Direct3DHook 是一个基于 Direct3D API 钩子实现游戏截图与实时叠加层(Overlay)的开源工具,支持 DirectX 9/10/11。上一篇文章我们讲了整体架构,本篇聚焦最核心的一个函数——`GetVTblAddresses`:它只有短短几行代码,却回答了"Direct3DHook 如何精准找到 Present、EndScene 等接口函数并替换它们"这个关键问题。读懂它

gitblog_00689的博客 385

python模拟鼠标点击和键盘输入的操作

所有代码都是网上百度出来的,通过个人实践找到适合自己的。 采用的python 库是 pymouse、pykeyboard 安装时直接pip安装的,pip install PyUserInput 安装不成功的可以参照http://www.lfd.uci.edu/~gohlke/pythonlibs/这个地址,内容很全 实现了一个最简单的输入密码,enter进入的登录过程 如果想遍历,可以使用itertools 包,很有用,具体用法这里不介绍了。 · 鼠标点击 有m.click(x, y, button, n)  — 点击,想x,y坐标,button:-1表示左键,-2表示右键,n:默认1次,2

ScriptHookV:打造专属GTA V模组世界的开源钩子框架

ScriptHookV是一款专为《侠盗猎车手V》(GTA V)设计的开源钩子框架,它允许开发者在离线环境下加载和运行自定义模组,为游戏注入无限创意。通过深入游戏引擎底层,ScriptHookV提供了强大的脚本注入能力和原生函数调用接口,让技术爱好者和创意开发者能够完全掌控游戏世界,实现从简单参数调整到复杂游戏机制改造的全方位定制。 ## 核心理念与价值主张 ScriptHookV的核心设计理念

gitblog_07817的博客 455

智能织梦:基于Rokid AR眼镜的家庭情感记忆增强系统设计与实践

本文介绍了基于Rokid AR眼镜的'智能织梦'系统,通过增强现实技术捕捉和重现家庭情感记忆。系统利用多模态传感器和轻量级情感识别模型,自动记录家庭互动中的情感峰值时刻,并生成沉浸式记忆片段。测试数据显示,该系统显著提升了家庭情感互动的频率和质量,特别适用于多代同堂家庭和记忆唤醒场景。

sre5engineer的博客 538

麒麟系统无法进入单用户模式该怎么办?

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 备注:部分问题/疑难杂症搜集于互联网。

**My Coding Family** 1822

ScriptHookV深度解析:构建GTA V高级游戏模组的开源脚本注入引擎

ScriptHookV是一款专为《侠盗猎车手V》(GTA V)设计的开源脚本注入引擎,它为技术开发者和高级用户提供了在不修改游戏原始文件的前提下,扩展游戏功能、创建自定义模组的强大能力。作为一款成熟的游戏模组框架,ScriptHookV通过创新的脚本注入技术和模块化架构,让开发者能够安全、高效地构建独立的脚本模组,为GTA V社区带来了无限的游戏玩法创新可能。 ## 核心机制解析:脚本注入引擎的

gitblog_00404的博客 735

uniapp [全端兼容] - 实现内网使用天地图离线地图,详解项目加载天地图的离线地图服务器部署与使用教程示例源码,Uniapp如何实现天地图的离线加载部署在内网访问(兼容H5、微信小程序、App)

uniapp天地图如何离线访问,无需网络调用天地图API,天地图离线地图,天地图——内网使用离线地图,uniapp中加载天地图的离线地图,uniAPP实现天地图离线访问,在内网中无法直接使用外网天地图资源怎么办,在uni-app中加载地图 -使用天地图的瓦片数据。UNIAPP天地图离线怎么使用,内网部署天地图,天地图离线瓦片,部分瓦片数据,天地图如何离线,下载天地图离线服务,并用Uniapp+天地图离线部署,天地图私有化部署,实现离线加载天地图,Java+uniapp天地图离线开发,uniapp项目中无网络

🏆 前端领域优质创作者 4908

深度解析Dalamud:FFXIV插件框架的架构设计与最佳实践

Dalamud作为《最终幻想14》(FFXIV)的插件框架和API,为游戏开发者提供了强大的扩展能力。这个开源项目通过模块化设计、安全的内存管理和高效的UI渲染系统,解决了传统游戏插件开发中的诸多痛点。本文将深入分析Dalamud的架构设计思想、核心模块实现原理,并提供实际应用场景和性能优化建议,帮助开发者充分掌握这一专业级插件框架。 **核心关键词:** FFXIV插件框架、内存安全机制、Im

gitblog_00248的博客 283

[低代码 + AI] 明道云与 Dify 的三种融合实践方式详解

融合方式技术路径优点局限或注意事项UI 嵌入iframe 表单嵌入快速集成、用户体验一致无法自定义交互逻辑明道云调用 DifyAPI 请求节点工作流自动化、逻辑灵活有 timeout 限制、需优化 promptDify 调用明道云插件或 API 调用节点可查询实际业务数据、增强 AI 智能需理解明道云 API 结构、权限设置复杂明道云与 Dify 的结合为低代码平台注入了智能动力。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1187

YOLO12涨点改进| 损失函数改进篇 |AAAI 2025| 一种小目标检测SDLoss损失函数,解决现有损失函数对不同目标尺度敏感度不足的局限,提高了网络检测不同尺度目标的敏感能力,助力高效涨点

本文提出了一种改进的小目标检测方法SDLoss,通过动态调整尺度损失与位置损失的权重,优化了YOLOv12模型的性能。针对红外小目标检测中存在的两个主要问题:1)标准卷积难以捕捉目标的高斯空间分布特性;2)现有损失函数对不同尺度目标的敏感度不足,研究团队开发了Pinwheel-shaped卷积(PConv)和Scale-based Dynamic损失函数(SDLoss)。PConv通过不对称卷积核设计显著提升感受野,SDLoss则根据目标大小动态平衡尺度与位置损失的影响。

Ai缝合怪、助力小伙伴高效发论文 238

Dalamud终极指南:重新定义FFXIV插件开发体验

还在为《最终幻想XIV》插件开发的复杂性而头疼吗?想象一下,当你试图为游戏添加一个简单的功能增强时,却需要处理内存注入、游戏版本适配、UI渲染等一系列底层技术细节。Dalamud框架正是为了解决这些痛点而生,它为FFXIV插件开发提供了一个完整的解决方案,让开发者能够专注于功能创新而非底层技术。 ## 从挣扎到优雅:插件开发者的进化之路 **传统开发模式**:每个插件开发者都需要重复造轮子,处

gitblog_01006的博客 713

28、基准剂量法:原理、应用与计算详解

本文详细介绍了基准剂量法(BMD)的原理、在监管机构中的应用以及具体的计算方法。内容涵盖样本量与BMD的关系、主要监管机构如EPA对BMD的应用、BMD的模型选择与数据拟合过程、拟合优度评估、下置信限(BMDL)计算,以及实验设计对BMD结果的影响。同时,还讨论了剂量指标和响应选择的关键问题,为理解和应用基准剂量法提供了全面的参考。

info6的博客 280

DouK-Downloader 上手指南:3 步把抖音视频批量存到本地

DouK-Downloader(仓库 TikTokDownloader)是一款完全开源、基于 HTTPX 的抖音 / TikTok 作品下载与数据采集工具:把链接或账号主页粘进去,视频、图集、音乐就按你定好的命名规则落到本地,作品字段还能同步导出成表格。它支持终端交互、后台监听、Web API 三种运行形态,采集数据可写入 CSV / XLSX / SQLite。 ## 先把一个链接里的视频存下

gitblog_01121的博客 240

融合双主干网络提升YOLOv8性能一种基于SOTA思想的目标检测改进

YOLOv8采用了单一的主干网络进行特征提取,通常是基于CSPDarknet作为骨干网络,在目标检测过程中通过不同的卷积层提取不同尺度的信息。虽然这种设计在大多数应用场景下表现出色,但在面对复杂背景、细节丰富的物体或小物体检测时,YOLOv8有时难以保持良好的精度。在本文中,我们提出了一种基于双主干网络的YOLOv8改进方案,通过结合先进的SOTA思想,全面提升了YOLOv8在目标检测任务中的表现。双主干网络架构。

博客 1154

S32K1XX Autosar开发实战|全网独家复现EB MCAL Port/Dio配置、详解引脚分层原理、实现经典跑马灯助力车载IO电控落地

在NXP S32K1XX系列车规MCU的AUTOSAR标准开发体系中,MCAL(微控制器抽象层)是软硬件解耦的核心载体,而Port端口模块与Dio数字IO模块是MCAL最基础、最核心的入门模块,也是车载指示灯、按键检测、继电器驱动、外设硬件启停控制的底层支撑。区别于传统裸机直接操作寄存器的开发方式,AUTOSAR架构采用分层隔离设计,Port负责硬件静态初始化、Dio负责动态电平操控,严格遵循车规级开发规范,杜绝硬件资源冲突、引脚配置混乱等问题。

getusushu的博客 44

DirectX Input 键盘实现

// DInputKeyboard.h: interface for the CDInputKeyboard class.////////////////////////////////////////////////////////////////////////#pragma once#define DIRECTINPUT_VERSION 0x800#include

zgl7903的专栏 4205

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Windows编程 DirectInput 鼠标和键盘的输入

版本:VS2015 语言:C++   书的第八章是一些数学的知识,以及一个图形库的创建。数学知识是有必要看一看的,我这里就不做多的介绍了,图形库的话反正你现在的win7+系统上也运行不了,看看就好。因为虽然这本书(《Windows游戏编程大师技巧》)非常的经典,但是代码都是比较老的,很多都已经过时了不能运行,所以我们要明确我们的目的,学好基础知识,编写一下程序练练手,熟悉熟悉Direct的流程

暗光之痕的博客 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: Starting a process from KernelMode
下一篇: Kport Direct Access I/O Ports under Win NT/2000/XP
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值