Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparent Memoization via func Annotation #4742

Merged
merged 12 commits into from
Mar 1, 2024
Merged

Conversation

Mzack9999
Copy link
Member

@Mzack9999 Mzack9999 commented Feb 7, 2024

Proposed changes

This PR implements a transparent memoization mechanism via functions annotations and AST parsing, requiring no changes within the codebase other than replacing package.Function(xx) with memo.Function(xx) (memo is the newly generated package with memoized functions).
A function to memoize should be annotated in the following way:

// file test.go
package test

// @memo
func A(xx, yy int) int {
    // heavy workload
   return complexResult
}

The new utility parses the go files and within a new destination package creates corresponding files exposing the same functions signature, but wrapped within a memoization mechanism:

  • Functions without params and with/without return values are wrapped around sync.Once that automatically declares local variables to store arbitrary return values, capture in-flight requests and return the result
  • Functions with params works in a similar manner, by caching a local struct that works as result values holder and capturing in-flight requests through a unique hash calculated as a combination of function name, and parameter values

Pros:

  • Adaptive runtime lazy clustering via function hashing with single flight request of stateless functions yielding same output
  • Traffic reduction of 10X

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Example

Generation is not automated via GH action on purpose as helpers should be fully stateless and intentionally marked by developer.
Command:

# generate memoized functions from annotated // @memo
$ go run . -src "/Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs"
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/mssql/mssql.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/mysql/mysql.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/mysql/mysql_private.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/oracle/oracle.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/pop3/pop3.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/postgres/postgres.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/rdp/rdp.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/redis/redis.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/rsync/rsync.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/smb/smb.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/smb/smb_private.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/smb/smbghost.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/smtp/smtp.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/ssh/ssh.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/telnet/telnet.go
2024/02/20 14:19:04 processing: /Users/marcornvh/go/src/github.com/projectdiscovery/nuclei/pkg/js/libs/vnc/vnc.go

$ echo 192.168.5.45 | nuclei -duc -verbose -rl 0 -t /Users/marcornvh/nuclei-templates/javascript/ -debug

Before:
Screenshot 2024-02-19 at 11 07 01
After:
Screenshot 2024-02-19 at 11 04 29

@Mzack9999 Mzack9999 marked this pull request as ready for review February 21, 2024 21:10
@Mzack9999 Mzack9999 self-assigned this Feb 21, 2024
@Mzack9999 Mzack9999 added the Type: Enhancement Most issues will probably ask for additions or changes. label Feb 21, 2024
Copy link
Member

@tarunKoyalwar tarunKoyalwar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm !

i think all of known independent heavy functions are memoized. with scan logs we will be able to identify and memoize more of them

@tarunKoyalwar tarunKoyalwar removed the request for review from Ice3man543 March 1, 2024 11:54
@ehsandeep ehsandeep merged commit 4c7a0f4 into dev Mar 1, 2024
9 of 12 checks passed
@ehsandeep ehsandeep deleted the feat-4473-memoize branch March 1, 2024 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement Most issues will probably ask for additions or changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement memoization of heavy javascript protocol calls such as ssh etc
3 participants