2

我认为这更多的是我缺乏对类型复杂性的理解。试图解决这个问题,我觉得我已经接近了几次,但还没有。

我正在尝试使用 Data.Binary 从流中读取。我已经到了下一节可能有一个或多个块的地步,但是在您开始解析流之前不知道信息。我在返回这些多个块时遇到问题。

这是代码,如果我以错误的方式进行此操作,请告诉我。但请记住,我需要能够轻松地使用相同的脚手架来写回流。

可能有用的信息:

  • 流是一个 PE 文件
  • 我正在使用镜头(fclabels)
  • DataDirectory 类型嵌套在其他类型的深处。
data DataDirectory = 
  DataDirectory { _dataEntryList ::  [DataEntry] } deriving (Show, Eq, Ord)

data DataEntry = DataEntry
  { _virtAddr :: Word32            -- VirtualAddress ^ relative virtual address of the table
  , _size :: Word32                -- Size ^ size of the table in bytes
  } deriving (Show, Eq, Ord)

parseDataDir :: Word32 -> Get DataDirectory
parseDataDir n = do
  -- PE Files have a maximum of 16 sections in the DataDir
  -- most windows tools just set this to 16 by default
  -- instead of hard-coding 16 sections we will verify
  let nDirs = fromIntegral (min mAX_NUMBEROF_DIRECTORY_ENTRIES n) :: Int
  dd_dentries <- parseDataEntry nDirs

  return $ DataDirectory dd_dentries

parseDataEntry :: Int -> [Get DataEntry] -- Not exactly sure on return type here
parseDataEntry n = 
  Prelude.replicate n $ getWord32le >>= \vAddr -> getWord32le >>= \ddSize -> return $ DataEntry vAddr ddSize

到目前为止,我一直避免抓取整个流并将nDirs乘以8 个字节来获取长度和解析。这当然适用于这种情况,但可能不会在其他地方降低范围。

4

1 回答 1

3

使用 Hoogle 搜索您想要的类型。

于 2012-09-14T15:18:49.630 回答