<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Martin Amps</title><link>https://ma.rtin.so/</link><description>Recent content on Martin Amps</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 20 May 2025 12:27:39 -0700</lastBuildDate><atom:link href="https://ma.rtin.so/index.xml" rel="self" type="application/rss+xml"/><item><title>Monitoring Claude Code with Datadog</title><link>https://ma.rtin.so/posts/monitoring-claude-code-with-datadog/</link><pubDate>Sun, 18 May 2025 12:33:52 -0500</pubDate><guid>https://ma.rtin.so/posts/monitoring-claude-code-with-datadog/</guid><description>&lt;p>This week, I noticed a &lt;a href="https://x.com/_catwu/status/1922352912996372578">tweet&lt;/a> announcing OpenTelemetry (OTel) support in &lt;a href="https://github.com/anthropics/claude-code">Claude Code&lt;/a> - Anthropic&amp;rsquo;s AI-powered coding assistant that lets you delegate tasks directly from your terminal. This new OTel integration allows you to stream token, session, and command metrics to any backend that speaks the OpenTelemetry Protocol (OTLP). Curiously, this feature hasn&amp;rsquo;t landed in the &lt;a href="https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md">official changelog&lt;/a> yet. Below, we&amp;rsquo;ll explore three different approaches to wiring Claude Code metrics into Datadog, the trade-offs between each method, and how to leverage these metrics effectively.&lt;/p>
&lt;div class="image-container">
 &lt;img src="https://ma.rtin.so/img/claude/claude-code-usage.png" alt="Datadog Dashboard excerpt showing Claude Code metrics" style="max-width: 420px;">
 &lt;div class="caption">Greg ships the most 🚀🔥&lt;/div>
&lt;/div></description></item><item><title>Reverse Engineering Netgear's Auth to extend my Meural</title><link>https://ma.rtin.so/posts/reverse-engineering-netgear-auth-to-extend-my-meural/</link><pubDate>Tue, 04 Aug 2020 12:33:52 -0500</pubDate><guid>https://ma.rtin.so/posts/reverse-engineering-netgear-auth-to-extend-my-meural/</guid><description>&lt;p>Back in January 2020 I shared a tweet demonstrating a &lt;a href="https://www.twilio.com">Twilio&lt;/a> integration with my &lt;a href="https://meural.netgear.com/canvasii">Meural Canvas&lt;/a> digital picture frame.&lt;/p>
&lt;div>
 &lt;blockquote class="twitter-tweet" data-dnt="true">
	&lt;p lang="en" dir="ltr">Used &lt;a href="https://twitter.com/hashtag/twilio?src=hash&amp;amp;ref_src=twsrc%5Etfw">#twilio&lt;/a> to add SMS to my ⁦&lt;a href="https://twitter.com/MeetMeural?ref_src=twsrc%5Etfw">@MeetMeural&lt;/a>⁩ Canvas today! &lt;a href="https://t.co/IRRH9HYV3o">pic.twitter.com/IRRH9HYV3o&lt;/a>&lt;/p>&amp;mdash; Martin Amps (@MartinAmps) &lt;a href="https://twitter.com/MartinAmps/status/1216458523007209472?ref_src=twsrc%5Etfw">January 12, 2020&lt;/a>
 &lt;/blockquote>
&lt;/div>
&lt;p>In the months since, guests have had a lot of fun with it and it’s been awesome seeing occasional surprise memories from friends pop up. That said, building that integration wasn’t the most straightforward task. I documented the journey (and failures) I took to arrive at the ultimate solution, with the intention of illustrating that reverse engineering is largely about persistence, and full of surprises. Most notably, I did not expect to encounter a dynamically generated virtual machine that generates and injects the headers required to validate authentication requests.&lt;/p>
&lt;p>&lt;em>Update&lt;/em>: Since posting, folks have noted this exact same technology is in use at Nordstrom (&lt;code>https://www.nordstrom.com/mwp/integration/ns_common.js?async&lt;/code>) and Target (&lt;code>https://assets.targetimg1.com/ssx/ssx.mod.js&lt;/code>). The solution appears to be &lt;a href="https://shapesecurity.com/">Shape Security&lt;/a>.&lt;/p></description></item><item><title>When HHVM Doesn't Work Quite Right</title><link>https://ma.rtin.so/posts/when-hhvm-doesnt-work-quite-right/</link><pubDate>Mon, 20 Jul 2015 19:22:09 -0500</pubDate><guid>https://ma.rtin.so/posts/when-hhvm-doesnt-work-quite-right/</guid><description>&lt;p>Despite generally resisting the hype train, in the past year I&amp;rsquo;ve jumped onto two relatively new Facebook projects. ReactJS and HHVM. I&amp;rsquo;m a huge proponent of both and enjoy working with them immensely. Except when I don&amp;rsquo;t.&lt;/p>
&lt;p>Around 3 months ago I chose HHVM for a new project and was initially very excited by the static analysis tools, built in profiling and great performance. Despite &lt;a href="https://code.facebook.com/posts/1607907626123431/under-the-hood-box-s-hhvm-migration/">many&lt;/a> &lt;a href="http://blog.wikimedia.org/2014/12/29/how-we-made-editing-wikipedia-twice-as-fast/">great&lt;/a> &lt;a href="https://www.facebook.com/notes/facebook-engineering/speeding-up-php-based-development-with-hhvm/10151170460698920">examples&lt;/a> of HHVM deployments, shortly after deploying to production we started hitting OOMs pretty frequently:&lt;/p>
&lt;div class="image-container">
 &lt;img src="https://ma.rtin.so/img/munin_hhvm_sizes.png" alt="HHVM Sizes (day)">
 &lt;div class="caption">HHVM memory usage showing OOM issues&lt;/div>
&lt;/div></description></item><item><title>Reverse Engineering Shopify Private Apis</title><link>https://ma.rtin.so/posts/reverse-engineering-shopify-private-apis/</link><pubDate>Fri, 01 Mar 2013 16:05:56 -0500</pubDate><guid>https://ma.rtin.so/posts/reverse-engineering-shopify-private-apis/</guid><description>&lt;p>Recently when working to migrate an e-commerce website to the aspiring &lt;a href="http://www.shopify.com">Shopify Cloud Platform&lt;/a>, generating coupon codes through the API was dismissed as being a obvious, &lt;a href="http://docs.chargify.com/api-coupons">simple&lt;/a>, and apparently &lt;a href="http://ecommerce.shopify.com/c/shopify-apps/t/is-there-an-api-for-coupon-codes-47500">one of the most requested features&lt;/a> &lt;strong>back in March, 2011.&lt;/strong>&lt;/p>
&lt;p>Unfortunately, I was wrong. So I contacted their support team to see what&amp;rsquo;s up!&lt;/p>
&lt;div class="image-container">
 &lt;img src="https://ma.rtin.so/img/shopify_support.png" alt="Shopify Support Snapshot">
 &lt;div class="caption">Thanks for the help, Brian. /s&lt;/div>
&lt;/div></description></item><item><title>Hacking Games to Make Them Better</title><link>https://ma.rtin.so/posts/hacking-games-to-make-them-better/</link><pubDate>Sat, 05 Feb 2011 14:32:22 -0500</pubDate><guid>https://ma.rtin.so/posts/hacking-games-to-make-them-better/</guid><description>&lt;p>The duplication of items has been a huge issue in a variety of games, ruining the economy in both official and in particular, private servers. A select few have figured out solutions to this, however the majority of which are offline solutions usually within stored procedures which hasn&amp;rsquo;t proven too reliable since the database is only amended every 5 minutes by default in Knight Online. As such, we needed to figure out a live way to do it.&lt;/p>
&lt;p>Fortunately, to communicate between the various server files a block of shared memory (or &lt;a href="http://msdn.microsoft.com/en-us/library/ms810613.aspx">Memory Mapped File&lt;/a>) is used. This means tapping into the data isn&amp;rsquo;t all that difficult. Reversing the structure is much trickier. As such, I&amp;rsquo;ll provide a near-complete structure below which will serve as a good base for this article.&lt;/p></description></item><item><title>Native Executable Patching</title><link>https://ma.rtin.so/posts/native-executable-patching/</link><pubDate>Sat, 05 Feb 2011 11:46:15 -0500</pubDate><guid>https://ma.rtin.so/posts/native-executable-patching/</guid><description>&lt;p>I was continuously asked how to apply security patches which were being released, instead of including instructions in each patch that I released I decided to put together a quick general guide. While this guide primarily focuses on Knight Online private server files, it serves as a good example and all terminology and methods will apply.&lt;/p>
&lt;p>To begin, we&amp;rsquo;ll start with the screen you&amp;rsquo;ll be prompted with just after you open ebenezer in &lt;a href="http://www.ollydbg.de/">OllyDbg&lt;/a>. I&amp;rsquo;m using Ollydbg because it&amp;rsquo;s easier, don&amp;rsquo;t use a hex editor it&amp;rsquo;s just silly. Olly will translate opcodes to hex for me and will make far less mistakes! Also note, I&amp;rsquo;m using the classic version (v1.10 final) - the v2 alpha is becoming increasingly popular and sports some exciting new features and some amazing improvements. So be sure to check it out! &lt;em>(Note: The original images were lost and the updated ones now reflect OllyDBG 2.01&lt;/em>).&lt;/p></description></item><item><title>PHP 5.3.3 x86 Vulnerability</title><link>https://ma.rtin.so/posts/php-5-3-3-x86-vulnerability/</link><pubDate>Thu, 13 Jan 2011 15:49:38 -0500</pubDate><guid>https://ma.rtin.so/posts/php-5-3-3-x86-vulnerability/</guid><description>&lt;p>Recently a new vulnerability has been exposed &lt;a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/Zend/zend_strtod.c?r1=307095&amp;amp;r2=307094&amp;amp;pathrev=307095&amp;amp;view=patch">(and patched)&lt;/a> which targets specific platforms as a result of certain assumptions made within the zend core (specifically zend_strtod.c) when handling floating-point arithmetic.&lt;/p>
&lt;p>The issue was only being manifested by gcc builds with &lt;code>-O2&lt;/code> so a recompile could fix it, reportedly &lt;code>-O0&lt;/code> fixes it but I would recommend using &lt;code>-mfpmath=sse&lt;/code> which will favour a newer instruction set rather than the older deprecated x87 math instructions. A diff of the new PHP revision revealed the actual committed patch was an additional keyword in a declaration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">double&lt;/span> &lt;span class="n">aadj&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">aadj1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">adj&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>vs&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">volatile&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">aadj&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">aadj1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">adj&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The volatile keyword instructs the compiler not to perform optimisations&lt;/p></description></item></channel></rss>