Codebase list golang-github-hillu-go-yara / e83d6b3
New upstream version 4.2.1 Sascha Steinbiss 2 years ago
15 changed file(s) with 202 addition(s) and 273 deletion(s). Raw diff Collapse all Expand all
6161
6262 This version of _go-yara_ can only be used with YARA 4.2 or later.
6363
64 Version of _go-yara_ compatible with YARA 4.0.x are available via the
64 Version of _go-yara_ compatible with YARA 4.1.x are available via the
6565 `v4.1.x` branch or tagged `v4.1.*` releases.
6666
6767 Version of _go-yara_ compatible with YARA 4.0.x are available via the
+0
-103
cbpool.go less more
0 // Copyright © 2015-2020 Hilko Bengen <bengen@hilluzination.de>
1 // All rights reserved.
2 //
3 // Use of this source code is governed by the license that can be
4 // found in the LICENSE file.
5
6 package yara
7
8 import (
9 "reflect"
10 "runtime"
11 "sync"
12 "unsafe"
13 )
14
15 // #include <stdlib.h>
16 import "C"
17
18 // cbPoolPool implements a key/value store for data that is safe
19 // to pass as callback data through CGO functions.
20 //
21 // The keys are pointers which do not directly reference the stored
22 // values, therefore any "Go pointer to Go pointer" errors are avoided.
23 type cbPool struct {
24 indices []int
25 objects []interface{}
26 m sync.RWMutex
27 }
28
29 // MakePool creates a Pool that can hold n elements.
30 func makecbPool(n int) *cbPool {
31 p := &cbPool{
32 indices: make([]int, 0),
33 objects: make([]interface{}, n),
34 }
35 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&p.indices))
36 hdr.Data = uintptr(C.calloc(C.size_t(n), C.size_t(unsafe.Sizeof(int(0)))))
37 hdr.Len = n
38 runtime.SetFinalizer(p, (*cbPool).Finalize)
39 return p
40 }
41
42 // Put adds an element to the cbPool, returning a stable pointer
43 // suitable for passing through CGO. It panics if the pool is full.
44 func (p *cbPool) Put(obj interface{}) unsafe.Pointer {
45 p.m.Lock()
46 defer p.m.Unlock()
47 for id, val := range p.indices {
48 if val != 0 {
49 continue
50 }
51 p.indices[id] = id + 1
52 p.objects[id] = obj
53 return unsafe.Pointer(&p.indices[id])
54 }
55 panic("cbPool storage exhausted")
56 }
57
58 func (p *cbPool) checkPointer(ptr unsafe.Pointer) {
59 if uintptr(ptr) < uintptr(unsafe.Pointer(&p.indices[0])) ||
60 uintptr(unsafe.Pointer(&p.indices[len(p.indices)-1])) < uintptr(ptr) {
61 panic("Attempt to access pool using invalid pointer")
62 }
63 }
64
65 // Get accesses an element stored in the cbPool, using a pointer
66 // previously returned by Put. It panics if the pointer is invalid or
67 // if it references an empty slot.
68 func (p *cbPool) Get(ptr unsafe.Pointer) interface{} {
69 p.m.RLock()
70 defer p.m.RUnlock()
71 p.checkPointer(ptr)
72 id := *(*int)(ptr) - 1
73 if id == -1 {
74 panic("Attempt to get nonexistent value from pool")
75 }
76 return p.objects[id]
77 }
78
79 // Delete removes an element from the cbPool, using a pointer previously
80 // returned by Put. It panics if the pointer is invalid or if it
81 // references an empty slot.
82 func (p *cbPool) Delete(ptr unsafe.Pointer) {
83 p.m.Lock()
84 defer p.m.Unlock()
85 p.checkPointer(ptr)
86 id := *(*int)(ptr) - 1
87 if id == -1 {
88 panic("Attempt to delete nonexistent value from pool")
89 }
90 p.indices[id] = 0
91 p.objects[id] = nil
92 return
93 }
94
95 func (p *cbPool) Finalize() {
96 p.m.Lock()
97 defer p.m.Unlock()
98 if p.indices != nil {
99 C.free(unsafe.Pointer(&p.indices[0]))
100 p.indices = nil
101 }
102 }
+0
-63
cbpool_test.go less more
0 // Copyright © 2015-2020 Hilko Bengen <bengen@hilluzination.de>
1 // All rights reserved.
2 //
3 // Use of this source code is governed by the license that can be
4 // found in the LICENSE file.
5
6 package yara
7
8 import (
9 "testing"
10 )
11
12 func TestBasic(t *testing.T) {
13 pool := makecbPool(32)
14 p1 := pool.Put("asdf")
15 p2 := pool.Put("ghjk")
16 s1, ok := pool.Get(p1).(string)
17 if !ok || s1 != "asdf" {
18 t.Errorf("s1: expected 'asdf', got '%v'", s1)
19 }
20 pool.Delete(p1)
21 i := func() interface{} {
22 defer func() {
23 if x := recover(); x != nil {
24 t.Logf("Get: Got expected panic: %v", x)
25 }
26 }()
27 x := pool.Get(p1)
28 t.Error("Get: No panic was triggered.")
29 return x
30 }()
31 if s1, ok := i.(string); ok || s1 == "asdf" {
32 t.Errorf("s1: expected nil, got '%v'", s1)
33 }
34 s2, ok := pool.Get(p2).(string)
35 if !ok || s2 != "ghjk" {
36 t.Errorf("s1: expected 'hjkl', got '%v'", s1)
37 }
38 pool.Delete(p2)
39 func() {
40 defer func() {
41 if x := recover(); x != nil {
42 t.Logf("Delete: Got expected panic: %v", x)
43 }
44 }()
45 pool.Delete(p2)
46 t.Error("Delete: No panic was triggered.")
47 }()
48
49 // Fill pool
50 for i := 0; i < 32; i++ {
51 pool.Put(i)
52 }
53 func() {
54 defer func() {
55 if x := recover(); x != nil {
56 t.Logf("full pool: Got expected panic: %v", x)
57 }
58 }()
59 pool.Put(100)
60 t.Error("full pool: No panic was triggered.")
61 }()
62 }
0 #include <yara.h>
1
2 /*
3 Wrappers functions whose sole purpose is converting uintptr as
4 returned by (*os.File).Fd() to HANDLE on Windows systems
5 */
6
7 #ifdef _WIN32
8
9 int _yr_compiler_add_fd(
10 YR_COMPILER* compiler,
11 int rules_fd,
12 const char* namespace_,
13 const char* file_name)
14 {
15 return yr_compiler_add_fd(compiler, (YR_FILE_DESCRIPTOR)(intptr_t)rules_fd, namespace_, file_name);
16 }
17
18 int _yr_rules_scan_fd(
19 YR_RULES* rules,
20 int fd,
21 int flags,
22 YR_CALLBACK_FUNC callback,
23 void* user_data,
24 int timeout)
25 {
26 return yr_rules_scan_fd(rules, (YR_FILE_DESCRIPTOR)(intptr_t)fd, flags, callback, user_data, timeout);
27 }
28
29 int _yr_scanner_scan_fd(
30 YR_SCANNER* scanner,
31 int fd)
32 {
33 return yr_scanner_scan_fd(scanner, (YR_FILE_DESCRIPTOR)(intptr_t)fd);
34 }
35
36 #endif
0 #ifndef _COMPAT_H
1 #define _COMPAT_H
2
3 #ifdef _WIN32
4 #define fdopen _fdopen
5 #define dup _dup
6 #endif
7
8 #ifdef _WIN32
9 int _yr_compiler_add_fd(
10 YR_COMPILER* compiler,
11 int rules_fd,
12 const char* namespace_,
13 const char* file_name);
14 #else
15 #define _yr_compiler_add_fd yr_compiler_add_fd
16 #endif
17
18 #ifdef _WIN32
19 int _yr_rules_scan_fd(
20 YR_RULES* rules,
21 int fd,
22 int flags,
23 YR_CALLBACK_FUNC callback,
24 void* user_data,
25 int timeout);
26 #else
27 #define _yr_rules_scan_fd yr_rules_scan_fd
28 #endif
29
30 #ifdef _WIN32
31 #include <stdint.h>
32 int _yr_scanner_scan_fd(
33 YR_SCANNER* scanner,
34 int fd);
35 #else
36 #define _yr_scanner_scan_fd yr_scanner_scan_fd
37 #endif
38
39 #endif /* _COMPAT_H */
66 package yara
77
88 /*
9 #ifdef _WIN32
10 #define fdopen _fdopen
11 #define dup _dup
12 #endif
13 #include <stdio.h>
14 #include <unistd.h>
15
169 #include <yara.h>
10 #include "compat.h"
1711
1812 void compilerCallback(int, char*, int, YR_RULE*, char*, void*);
1913 char* includeCallback(char*, char*, char*, void*);
3024
3125 //export compilerCallback
3226 func compilerCallback(errorLevel C.int, filename *C.char, linenumber C.int, rule *C.YR_RULE, message *C.char, userData unsafe.Pointer) {
33 c := callbackData.Get(userData).(*Compiler)
27 c := cgoHandle(userData).Value().(*Compiler)
3428 msg := CompilerMessage{
3529 Filename: C.GoString(filename),
3630 Line: int(linenumber),
5953 Errors []CompilerMessage
6054 Warnings []CompilerMessage
6155 // used for include callback
62 callbackData unsafe.Pointer
56 callbackData cgoHandle
6357 cptr *C.YR_COMPILER
6458 }
6559
9488 runtime.SetFinalizer(c, nil)
9589 }
9690
97 func (c *Compiler) setCallbackData(ptr unsafe.Pointer) {
98 if c.callbackData != nil {
99 callbackData.Delete(c.callbackData)
91 func (c *Compiler) setCallbackData(ptr cgoHandle) {
92 if c.callbackData != 0 {
93 c.callbackData.Delete()
10094 }
10195 c.callbackData = ptr
10296 }
117111 }
118112 filename := C.CString(file.Name())
119113 defer C.free(unsafe.Pointer(filename))
120 id := callbackData.Put(c)
121 defer callbackData.Delete(id)
122 C.yr_compiler_set_callback(c.cptr, C.YR_COMPILER_CALLBACK_FUNC(C.compilerCallback), id)
123 numErrors := int(C.yr_compiler_add_fd(c.cptr, (C.YR_FILE_DESCRIPTOR)(file.Fd()), ns, filename))
114 id := cgoNewHandle(c)
115 defer id.Delete()
116 C.yr_compiler_set_callback(c.cptr, C.YR_COMPILER_CALLBACK_FUNC(C.compilerCallback), unsafe.Pointer(id))
117 numErrors := int(C._yr_compiler_add_fd(c.cptr, C.int(file.Fd()), ns, filename))
124118 if numErrors > 0 {
125119 var buf [1024]C.char
126120 msg := C.GoString(C.yr_compiler_get_error_message(
147141 }
148142 crules := C.CString(rules)
149143 defer C.free(unsafe.Pointer(crules))
150 id := callbackData.Put(c)
151 defer callbackData.Delete(id)
152 C.yr_compiler_set_callback(c.cptr, C.YR_COMPILER_CALLBACK_FUNC(C.compilerCallback), id)
144 id := cgoNewHandle(c)
145 defer id.Delete()
146 C.yr_compiler_set_callback(c.cptr, C.YR_COMPILER_CALLBACK_FUNC(C.compilerCallback), unsafe.Pointer(id))
153147 numErrors := int(C.yr_compiler_add_string(c.cptr, crules, ns))
154148 if numErrors > 0 {
155149 var buf [1024]C.char
210204
211205 //export includeCallback
212206 func includeCallback(name, filename, namespace *C.char, userData unsafe.Pointer) *C.char {
213 callbackFunc := callbackData.Get(userData).(CompilerIncludeFunc)
207 callbackFunc := cgoHandle(userData).Value().(CompilerIncludeFunc)
214208 if buf := callbackFunc(
215209 C.GoString(name), C.GoString(filename), C.GoString(namespace),
216210 ); buf != nil {
254248 c.DisableIncludes()
255249 return
256250 }
257 id := callbackData.Put(cb)
251 id := cgoNewHandle(cb)
258252 c.setCallbackData(id)
259253 C.yr_compiler_set_include_callback(
260254 c.cptr,
261255 C.YR_COMPILER_INCLUDE_CALLBACK_FUNC(C.includeCallback),
262256 C.YR_COMPILER_INCLUDE_FREE_FUNC(C.freeCallback),
263 id,
257 unsafe.Pointer(id),
264258 )
265259 runtime.KeepAlive(c)
266260 return
270264 // See yr_compiler_set_include_callbacks.
271265 func (c *Compiler) DisableIncludes() {
272266 C.yr_compiler_set_include_callback(c.cptr, nil, nil, nil)
273 c.setCallbackData(nil)
267 c.setCallbackData(0)
274268 runtime.KeepAlive(c)
275269 return
276270 }
00 module github.com/hillu/go-yara/v4
1
2 go 1.15
0 //+build go1.17
1
2 // This variant contains a trivial wrapper around "runtime/cgo".Handle.
3
4 package yara
5
6 import "runtime/cgo"
7
8 type cgoHandle cgo.Handle
9
10 func (h cgoHandle) Value() interface{} { return cgo.Handle(h).Value() }
11
12 func (h cgoHandle) Delete() { cgo.Handle(h).Delete() }
13
14 func cgoNewHandle(v interface{}) cgoHandle { return cgoHandle(cgo.NewHandle(v)) }
0 //+build !go1.17
1
2 // This variant contains a backport of go 1.18's "runtime/cgo".Handle.
3
4 package yara
5
6 import (
7 "sync"
8 "sync/atomic"
9 )
10
11 type cgoHandle uintptr
12
13 func cgoNewHandle(v interface{}) cgoHandle {
14 h := atomic.AddUintptr(&handleIdx, 1)
15 if h == 0 {
16 panic("cgoNewHandle: ran out of handle space")
17 }
18
19 handles.Store(h, v)
20 return cgoHandle(h)
21 }
22
23 func (h cgoHandle) Value() interface{} {
24 v, ok := handles.Load(uintptr(h))
25 if !ok {
26 panic("cgoHandle: misuse of an invalid Handle")
27 }
28 return v
29 }
30
31 func (h cgoHandle) Delete() {
32 _, ok := handles.LoadAndDelete(uintptr(h))
33 if !ok {
34 panic("cgoHandle: misuse of an invalid Handle")
35 }
36 }
37
38 var (
39 handles = sync.Map{}
40 handleIdx uintptr
41 )
6161 return
6262 }
6363
64 // The caller is responsible to remove cmbi.context from callbackData
65 // pool.
64 // The caller is responsible to delete the cgoHandle cmbi.context.
6665 func makeCMemoryBlockIterator(c *memoryBlockIteratorContainer) (cmbi *C.YR_MEMORY_BLOCK_ITERATOR) {
6766 cmbi = &C.YR_MEMORY_BLOCK_ITERATOR{
68 context: callbackData.Put(c),
69 first: C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorFirst),
70 next: C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorNext),
67 context: unsafe.Pointer(cgoNewHandle(c)),
68 first: C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorFirst),
69 next: C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorNext),
7170 }
7271 if _, implementsFilesize := c.MemoryBlockIterator.(MemoryBlockIteratorWithFilesize); implementsFilesize {
7372 cmbi.file_size = C.YR_MEMORY_BLOCK_ITERATOR_SIZE_FUNC(C.memoryBlockIteratorFilesize)
108107 //
109108 //export memoryBlockFetch
110109 func memoryBlockFetch(cblock *C.YR_MEMORY_BLOCK) *C.uint8_t {
111 c := callbackData.Get(cblock.context).(*memoryBlockIteratorContainer)
110 c := cgoHandle(cblock.context).Value().(*memoryBlockIteratorContainer)
112111 c.realloc(int(cblock.size))
113112 c.MemoryBlock.FetchData(c.buf)
114113 return (*C.uint8_t)(unsafe.Pointer(&c.buf[0]))
143142 //
144143 //export memoryBlockIteratorFirst
145144 func memoryBlockIteratorFirst(cmbi *C.YR_MEMORY_BLOCK_ITERATOR) *C.YR_MEMORY_BLOCK {
146 c := callbackData.Get(cmbi.context).(*memoryBlockIteratorContainer)
145 c := cgoHandle(cmbi.context).Value().(*memoryBlockIteratorContainer)
147146 c.MemoryBlock = c.MemoryBlockIterator.First()
148147 return memoryBlockIteratorCommon(cmbi, c)
149148 }
153152 //
154153 //export memoryBlockIteratorNext
155154 func memoryBlockIteratorNext(cmbi *C.YR_MEMORY_BLOCK_ITERATOR) *C.YR_MEMORY_BLOCK {
156 c := callbackData.Get(cmbi.context).(*memoryBlockIteratorContainer)
155 c := cgoHandle(cmbi.context).Value().(*memoryBlockIteratorContainer)
157156 c.MemoryBlock = c.MemoryBlockIterator.Next()
158157 return memoryBlockIteratorCommon(cmbi, c)
159158 }
160159
161160 //export memoryBlockIteratorFilesize
162161 func memoryBlockIteratorFilesize(cmbi *C.YR_MEMORY_BLOCK_ITERATOR) C.uint64_t {
163 c := callbackData.Get(cmbi.context).(*memoryBlockIteratorContainer)
162 c := cgoHandle(cmbi.context).Value().(*memoryBlockIteratorContainer)
164163 return C.uint64_t(c.MemoryBlockIterator.(MemoryBlockIteratorWithFilesize).Filesize())
165164 }
77
88 /*
99 #include <yara.h>
10
11 #ifdef _WIN32
12 #include <stdint.h>
13 // Helper function that is merely used to cast fd from int to HANDLE.
14 // CGO treats HANDLE (void*) to an unsafe.Pointer. This confuses the
15 // go1.4 garbage collector, leading to runtime errors such as:
16 //
17 // runtime: garbage collector found invalid heap pointer *(0x5b80ff14+0x4)=0xa0 s=nil
18 int _yr_rules_scan_fd(
19 YR_RULES* rules,
20 int fd,
21 int flags,
22 YR_CALLBACK_FUNC callback,
23 void* user_data,
24 int timeout)
25 {
26 return yr_rules_scan_fd(rules, (YR_FILE_DESCRIPTOR)(intptr_t)fd, flags, callback, user_data, timeout);
27 }
28 #else
29 #define _yr_rules_scan_fd yr_rules_scan_fd
30 #endif
10 #include "compat.h"
3111
3212 size_t streamRead(void* ptr, size_t size, size_t nmemb, void* user_data);
3313 size_t streamWrite(void* ptr, size_t size, size_t nmemb, void* user_data);
9676 if len(buf) > 0 {
9777 ptr = (*C.uint8_t)(unsafe.Pointer(&(buf[0])))
9878 }
99 id := callbackData.Put(makeScanCallbackContainer(cb, r))
100 defer callbackData.Delete(id)
79 id := cgoNewHandle(makeScanCallbackContainer(cb, r))
80 defer id.Delete()
10181 err = newError(C.yr_rules_scan_mem(
10282 r.cptr,
10383 ptr,
10484 C.size_t(len(buf)),
10585 flags.withReportFlags(cb),
10686 C.YR_CALLBACK_FUNC(C.scanCallbackFunc),
107 id,
87 unsafe.Pointer(id),
10888 C.int(timeout/time.Second)))
10989 runtime.KeepAlive(r)
11090 return
11696 func (r *Rules) ScanFile(filename string, flags ScanFlags, timeout time.Duration, cb ScanCallback) (err error) {
11797 cfilename := C.CString(filename)
11898 defer C.free(unsafe.Pointer(cfilename))
119 id := callbackData.Put(makeScanCallbackContainer(cb, r))
120 defer callbackData.Delete(id)
99 id := cgoNewHandle(makeScanCallbackContainer(cb, r))
100 defer id.Delete()
121101 err = newError(C.yr_rules_scan_file(
122102 r.cptr,
123103 cfilename,
124104 flags.withReportFlags(cb),
125105 C.YR_CALLBACK_FUNC(C.scanCallbackFunc),
126 id,
106 unsafe.Pointer(id),
127107 C.int(timeout/time.Second)))
128108 runtime.KeepAlive(r)
129109 return
133113 // emitted by libyara, the corresponding method on the ScanCallback
134114 // object is called.
135115 func (r *Rules) ScanFileDescriptor(fd uintptr, flags ScanFlags, timeout time.Duration, cb ScanCallback) (err error) {
136 id := callbackData.Put(makeScanCallbackContainer(cb, r))
137 defer callbackData.Delete(id)
116 id := cgoNewHandle(makeScanCallbackContainer(cb, r))
117 defer id.Delete()
138118 err = newError(C._yr_rules_scan_fd(
139119 r.cptr,
140120 C.int(fd),
141121 flags.withReportFlags(cb),
142122 C.YR_CALLBACK_FUNC(C.scanCallbackFunc),
143 id,
123 unsafe.Pointer(id),
144124 C.int(timeout/time.Second)))
145125 runtime.KeepAlive(r)
146126 return
150130 // every event emitted by libyara, the corresponding method on the
151131 // ScanCallback object is called.
152132 func (r *Rules) ScanProc(pid int, flags ScanFlags, timeout time.Duration, cb ScanCallback) (err error) {
153 id := callbackData.Put(makeScanCallbackContainer(cb, r))
154 defer callbackData.Delete(id)
133 id := cgoNewHandle(makeScanCallbackContainer(cb, r))
134 defer id.Delete()
155135 err = newError(C.yr_rules_scan_proc(
156136 r.cptr,
157137 C.int(pid),
158138 flags.withReportFlags(cb),
159139 C.YR_CALLBACK_FUNC(C.scanCallbackFunc),
160 id,
140 unsafe.Pointer(id),
161141 C.int(timeout/time.Second)))
162142 runtime.KeepAlive(r)
163143 return
170150 c := makeMemoryBlockIteratorContainer(mbi)
171151 defer c.free()
172152 cmbi := makeCMemoryBlockIterator(c)
173 defer callbackData.Delete(cmbi.context)
174 id := callbackData.Put(makeScanCallbackContainer(cb, r))
175 defer callbackData.Delete(id)
153 defer cgoHandle(cmbi.context).Delete()
154 id := cgoNewHandle(makeScanCallbackContainer(cb, r))
155 defer id.Delete()
176156 err = newError(C.yr_rules_scan_mem_blocks(
177157 r.cptr,
178158 cmbi,
179159 flags.withReportFlags(cb),
180160 C.YR_CALLBACK_FUNC(C.scanCallbackFunc),
181 id,
161 unsafe.Pointer(id),
182162 C.int(timeout/time.Second)))
183163 runtime.KeepAlive(r)
184164 return
207187
208188 // Write writes a compiled ruleset to an io.Writer.
209189 func (r *Rules) Write(wr io.Writer) (err error) {
210 id := callbackData.Put(wr)
211 defer callbackData.Delete(id)
190 id := cgoNewHandle(wr)
191 defer id.Delete()
212192
213193 stream := C.YR_STREAM{
214194 write: C.YR_STREAM_WRITE_FUNC(C.streamWrite),
215195 // The complaint from go vet about possible misuse of
216196 // unsafe.Pointer is wrong: user_data will be interpreted as
217197 // an uintptr on the other side of the callback
218 user_data: id,
198 user_data: unsafe.Pointer(id),
219199 }
220200 err = newError(C.yr_rules_save_stream(r.cptr, &stream))
221201 runtime.KeepAlive(r)
224204
225205 // ReadRules retrieves a compiled ruleset from an io.Reader.
226206 func ReadRules(rd io.Reader) (*Rules, error) {
227 id := callbackData.Put(rd)
228 defer callbackData.Delete(id)
207 id := cgoNewHandle(rd)
208 defer id.Delete()
229209
230210 stream := C.YR_STREAM{
231211 read: C.YR_STREAM_READ_FUNC(C.streamRead),
232212 // The complaint from go vet about possible misuse of
233213 // unsafe.Pointer is wrong, see above.
234 user_data: id,
214 user_data: unsafe.Pointer(id),
235215 }
236216 r := &Rules{}
237217 if err := newError(C.yr_rules_load_stream(&stream, &(r.cptr))); err != nil {
102102
103103 //export scanCallbackFunc
104104 func scanCallbackFunc(ctx *C.YR_SCAN_CONTEXT, message C.int, messageData, userData unsafe.Pointer) C.int {
105 cbc, ok := callbackData.Get(userData).(*scanCallbackContainer)
105 cbc, ok := cgoHandle(userData).Value().(*scanCallbackContainer)
106106 s := &ScanContext{cptr: ctx}
107107 if !ok {
108108 return C.CALLBACK_ERROR
77
88 /*
99 #include <yara.h>
10
11 #ifdef _WIN32
12 #include <stdint.h>
13 int _yr_scanner_scan_fd(
14 YR_SCANNER* scanner,
15 int fd)
16 {
17 return yr_scanner_scan_fd(scanner, (YR_FILE_DESCRIPTOR)(intptr_t)fd);
18 }
19 #else
20 #define _yr_scanner_scan_fd yr_scanner_scan_fd
21 #endif
10 #include "compat.h"
2211
2312 int scanCallbackFunc(YR_SCAN_CONTEXT*, int, void*, void*);
2413 */
126115 }
127116
128117 // putCallbackData stores the scanner's callback object in
129 // callbackData, returning a pointer. If no callback object has been
118 // a cgoHandle. If no callback object has been
130119 // set, it is initialized with the pointer to an empty ScanRules
131 // object. The object must be removed from callbackData by the calling
132 // ScanXxxx function.
133 func (s *Scanner) putCallbackData() unsafe.Pointer {
120 // object. The handle must be deleted by the calling ScanXxxx function.
121 func (s *Scanner) putCallbackData() cgoHandle {
134122 if _, ok := s.Callback.(ScanCallback); !ok {
135123 s.Callback = &MatchRules{}
136124 }
137 ptr := callbackData.Put(makeScanCallbackContainer(s.Callback, s.rules))
138 C.yr_scanner_set_callback(s.cptr, C.YR_CALLBACK_FUNC(C.scanCallbackFunc), ptr)
125 ptr := cgoNewHandle(makeScanCallbackContainer(s.Callback, s.rules))
126 C.yr_scanner_set_callback(s.cptr, C.YR_CALLBACK_FUNC(C.scanCallbackFunc), unsafe.Pointer(ptr))
139127 return ptr
140128 }
141129
150138 }
151139
152140 cbPtr := s.putCallbackData()
153 defer callbackData.Delete(cbPtr)
141 defer cbPtr.Delete()
154142
155143 C.yr_scanner_set_flags(s.cptr, s.flags.withReportFlags(s.Callback))
156144 err = newError(C.yr_scanner_scan_mem(
170158 defer C.free(unsafe.Pointer(cfilename))
171159
172160 cbPtr := s.putCallbackData()
173 defer callbackData.Delete(cbPtr)
161 defer cbPtr.Delete()
174162
175163 C.yr_scanner_set_flags(s.cptr, s.flags.withReportFlags(s.Callback))
176164 err = newError(C.yr_scanner_scan_file(
187175 // SetCAllback, it is initialized with an empty MatchRules object.
188176 func (s *Scanner) ScanFileDescriptor(fd uintptr) (err error) {
189177 cbPtr := s.putCallbackData()
190 defer callbackData.Delete(cbPtr)
178 defer cbPtr.Delete()
191179
192180 C.yr_scanner_set_flags(s.cptr, s.flags.withReportFlags(s.Callback))
193181 err = newError(C._yr_scanner_scan_fd(
204192 // SetCAllback, it is initialized with an empty MatchRules object.
205193 func (s *Scanner) ScanProc(pid int) (err error) {
206194 cbPtr := s.putCallbackData()
207 defer callbackData.Delete(cbPtr)
195 defer cbPtr.Delete()
208196
209197 C.yr_scanner_set_flags(s.cptr, s.flags.withReportFlags(s.Callback))
210198 err = newError(C.yr_scanner_scan_proc(
223211 c := makeMemoryBlockIteratorContainer(mbi)
224212 defer c.free()
225213 cmbi := makeCMemoryBlockIterator(c)
226 defer callbackData.Delete(cmbi.context)
227
228 cbPtr := s.putCallbackData()
229 defer callbackData.Delete(cbPtr)
214 defer cgoHandle(cmbi.context).Delete()
215
216 cbPtr := s.putCallbackData()
217 defer cbPtr.Delete()
230218
231219 C.yr_scanner_set_flags(s.cptr, s.flags.withReportFlags(s.Callback))
232220 err = newError(C.yr_scanner_scan_mem_blocks(
1919 if size == 0 || nmemb == 0 {
2020 return nmemb
2121 }
22 reader := callbackData.Get(userData).(io.Reader)
22 reader := cgoHandle(userData).Value().(io.Reader)
2323 buf := make([]byte, 0)
2424 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
2525 hdr.Data = uintptr(ptr)
5252 if size == 0 || nmemb == 0 {
5353 return nmemb
5454 }
55 writer := callbackData.Get(userData).(io.Writer)
55 writer := cgoHandle(userData).Value().(io.Writer)
5656 buf := make([]byte, 0)
5757 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
5858 hdr.Data = uintptr(ptr)
44 // found in the LICENSE file.
55
66 package yara
7
8 var callbackData = makecbPool(256)
97
108 func toint64(number interface{}) int64 {
119 switch number.(type) {