1

我是 Firefox 扩展开发的新手。

我们得到了一个 firefox 扩展,它使用 NSS 3.12 为 22 之前的所有版本的 firefox(不包括 22)签署 PDF(封装签名)。在那个 Firefox 版本之后,它使用的 NSS 中有一个修改。这个扩展是一个使用 ctypes 调用 C++ 函数的 JS 扩展。

我的目标是让这个扩展在 Firefox 22 以上的版本上工作。

我进入了我的扩展库 nspr4.dll、nss3.dll、nssutil3.dll、plc4.dll、plds4.dll,这些文件是使用 NSS 版本的 mozilla-build 生成的。

我们得到的代码与您可以在此处找到的代码非常相似:https ://github.com/metajack/nss/blob/master/cmd/p7sign/p7sign.c

该代码运行良好(它成功获取证书信息,使用 SEC_PKCS7CreateSignedData(...) 创建 SEC_PKCS7ContentInfo,使用 SEC_PKCS7SetContent(..) 设置其内容,包括证书链)直到调用 SEC_PKCS7Encode。使用此方法时,fireFox 会崩溃。

我使用 WinDBG 来获取堆栈跟踪,这就是我得到的:

*******************************************************************************
*                                                                             *
*                           Exception Analysis                                *
*                                                                             *
*******************************************************************************


FAULTING_IP: 
plds4!PL_HashTableLookupConst+c
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch]

EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
.exr 0xffffffffffffffff
ExceptionAddress: 00000000721b1c7c (plds4!PL_HashTableLookupConst+0x000000000000000c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 000000000000000c
Attempt to read from address 000000000000000c

CONTEXT:  0000000000000000 -- (.cxr 0x0;r)
.cxr 0x0;r
eax=063e7b90 ebx=00000000 ecx=dd4c128b edx=063e7c98 esi=063e7b90 edi=00000000
eip=721b1c7c esp=0067c1e8 ebp=063e7898 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210206
plds4!PL_HashTableLookupConst+0xc:
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch] ds:002b:0000000c=????????
.cxr

FAULTING_THREAD:  00000000000016cc

PROCESS_NAME:  firefox.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - L

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - L

EXCEPTION_PARAMETER1:  0000000000000000

EXCEPTION_PARAMETER2:  000000000000000c

READ_ADDRESS:  000000000000000c 

FOLLOWUP_IP: 
plds4!PL_HashTableLookupConst+c
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch]

APPLICATION_VERIFIER_FLAGS:  0

APP:  firefox.exe

ANALYSIS_VERSION: 6.3.9600.17029 (debuggers(dbg).140219-1702) amd64fre

BUGCHECK_STR:  APPLICATION_FAULT_NULL_CLASS_PTR_READ_ZEROED_STACK

PRIMARY_PROBLEM_CLASS:  NULL_CLASS_PTR_READ

DEFAULT_BUCKET_ID:  NULL_CLASS_PTR_READ

LAST_CONTROL_TRANSFER:  from 00000000716b9231 to 00000000721b1c7c

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
0067c1f4 716b9231 00000000 063e7b90 063e7ca0 plds4!PL_HashTableLookupConst+0xc
00000000 00000000 00000000 00000000 00000000 nssutil3!SECOID_FindOIDTag_Util+0x11


STACK_COMMAND:  .cxr 0x0 ; kb

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  plds4!PL_HashTableLookupConst+c

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: plds4

IMAGE_NAME:  plds4.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  53a04c1e

FAILURE_BUCKET_ID:  NULL_CLASS_PTR_READ_c0000005_plds4.dll!PL_HashTableLookupConst

BUCKET_ID:  
APPLICATION_FAULT_NULL_CLASS_PTR_READ_ZEROED_STACK_plds4!PL_HashTableLookupConst+c

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:                          um:null_class_ptr_read_c0000005_plds4.dll!pl_hashtablelookupconst

FAILURE_ID_HASH:  {2f7bb160-6820-dd99-35e3-03bb56e8aca4}

Followup: MachineOwner
---------

这意味着在调用 SEC_PKCS7Encode 时,它​​会调用 PLDS4.DLL 中导致 Firefox 崩溃的方法。

我尝试使用空的 SEC_PKCS7ContentInfo(使用 SEC_PKCS7CreateData())调用 SEC_PKCS7Encode,但它没有崩溃。仅当填充 SEC_PKCS7ContentInfo 时才会崩溃。

经过一些研究,我发现了这个问题:https ://bugzilla.mozilla.org/show_bug.cgi?id=702307 我不知道这个问题是否是导致我的 Firefox 崩溃的原因。

我尝试使用不同版本的NSS(3.12、3.15、3.16.2)结果完全一样。

有没有办法避免这个问题?有没有办法在不使用 SEC_PKCS7Encode 的情况下对我的 SEC_PKCS7ContentInfo 进行编码?

提前致谢。

编辑 2014 年 11 月 7 日

正如 nmaier 在响应中提到的那样,问题似乎是两个不同 NSS 的利用(即使它是相同版本的 nss,因为 Mozilla 中的一个具有不同的依赖关系,例如)。

签名(和其他过程)在 C++ 项目中完成(我的扩展使用的 Dll 是从这个项目与 Visual Studio 2013 生成的)。但是为了编译和构建 DLL,项目必须有 NSS 库和包含(这很正常,我在项目中使用 NSS 方法)。主要问题是如何引用 MOZILLA FIREFOX NSS 库和包含。我编译了一个与Firefox的NSS相同版本的NSS,但是依赖不同。我还尝试获取 FireFox 源并使用 mozilla 编译它的 NSS,但我遇到了错误。如果我可以获得 Firefox 的 NSS 库,我可以在我的扩展中加载 Firefox 的 NSS dll。

如何在我的 C++ 项目中引用 Mozilla firefox 的 NSS 库以使用正确的库构建我的自定义 DLL?

4

2 回答 2

1

我希望这会行为不端:Firefox 已经加载了 nss 和依赖库。尝试再次加载“相同”的 DLL,但在不同的版本中将导致 DLL 加载器使用 Firefox 附带的初始加载的 DLL 的导出来解析依赖导入,而不是相同 DLL 的旧版本的副本。这种新旧东西的混合然后破裂和崩溃。

你应该:

  • 首先不构建和发布 DLL...
  • 但使用 Firefox 已经附带的 DLL。(例如见WeaveCrypto.js
  • ctypes如果它使用的 nss API 在此期间发生变化,请更新您的调用。
  • 确保您的ctypes声明是正确的并且仍然是最新的。
于 2014-07-04T19:07:53.270 回答
1

我做的。

为了在我的项目中指定 firefox 的 NSS,我必须使用 mozilla-build 工具构建一个完整的 Firefox,然后恢复 Libs 并包含在 OBJ 目录中。

这会将我的项目生成为 DLL,它引用了良好版本的 DLL。

(这不是我认为最好的解决方案,因为 Firefox 21 和 22 之间的 NSS 发生了 NSS 更改,所以我的解决方案仅适用于 22 和包含 NSS 更改的下一个版本的 Firefox 之间的 Firefox。)

于 2014-07-21T07:53:58.923 回答